ObjFW  Check-in [d051b1302d]

Overview
Comment:Add OFString (OFHashing) category.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: d051b1302d85d252f791a360f5bd583f4ba74e31cf84003681285a62f3ee0083
User & Date: js on 2009-07-17 12:41:48
Other Links: manifest | tags
Context
2009-07-17
15:16
Initial OFXMLParser implementation. There's still a LOT missing. check-in: 8f4d7a5b74 user: js tags: trunk
12:41
Add OFString (OFHashing) category. check-in: d051b1302d user: js tags: trunk
11:25
Use +[stringWithCString:andLength:] in -[readLine]. check-in: 328decd247 user: js tags: trunk
Changes

Modified src/OFHashes.h from [6aec6298e0] to [0d09241315].

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15


16
17
18
19
20
21
22
/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import "OFObject.h"


#define MD5_DIGEST_SIZE	 16
#define SHA1_DIGEST_SIZE 20



/**
 * The OFMD5Hash class provides functions to create an MD5 hash.
 */
@interface OFMD5Hash: OFObject
{
	uint32_t buf[4];












>



>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import "OFObject.h"
#import "OFString.h"

#define MD5_DIGEST_SIZE	 16
#define SHA1_DIGEST_SIZE 20

extern int _OFHashing_reference;

/**
 * The OFMD5Hash class provides functions to create an MD5 hash.
 */
@interface OFMD5Hash: OFObject
{
	uint32_t buf[4];
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
- updateWithBuffer: (const char*)buf
	    ofSize: (size_t)size;

/**
 * \return A buffer containing the hash (MD5_DIGEST_SIZE = 16 bytes).
 *	   The buffer is part of object's memory pool.
 */
- (char*)digest;
@end

/**
 * The OFSHA1Hash class provides functions to create an SHA1 hash.
 */
@interface OFSHA1Hash: OFObject
{
	uint32_t state[5];
	uint64_t count;
	char	 buffer[64];
	char	 digest[SHA1_DIGEST_SIZE];

	BOOL	 calculated;
}

/**
 * \return A new autoreleased SHA1 Hash
 */







|










|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
- updateWithBuffer: (const char*)buf
	    ofSize: (size_t)size;

/**
 * \return A buffer containing the hash (MD5_DIGEST_SIZE = 16 bytes).
 *	   The buffer is part of object's memory pool.
 */
- (uint8_t*)digest;
@end

/**
 * The OFSHA1Hash class provides functions to create an SHA1 hash.
 */
@interface OFSHA1Hash: OFObject
{
	uint32_t state[5];
	uint64_t count;
	char	 buffer[64];
	uint8_t	 digest[SHA1_DIGEST_SIZE];

	BOOL	 calculated;
}

/**
 * \return A new autoreleased SHA1 Hash
 */
78
79
80
81
82
83
84
85
86















- updateWithBuffer: (const char*)buf
	    ofSize: (size_t)size;

/**
 * \return A buffer containing the hash (SHA1_DIGEST_SIZE = 20 bytes).
 *	   The buffer is part of object's memory pool.
 */
- (char*)digest;
@end






















|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
- updateWithBuffer: (const char*)buf
	    ofSize: (size_t)size;

/**
 * \return A buffer containing the hash (SHA1_DIGEST_SIZE = 20 bytes).
 *	   The buffer is part of object's memory pool.
 */
- (uint8_t*)digest;
@end

/**
 * The OFHashing category provides methods to calculate hashes for strings.
 */
@interface OFString (OFHashing)
/**
 * \return The MD5 hash of the string as an autoreleased OFString
 */
- (OFString*)md5Hash;

/**
 * \return The SHA1 hash of the string as an autoreleased OFString
 */
- (OFString*)sha1Hash;
@end

Modified src/OFHashes.m from [dab01f181a] to [3030cde43c].

10
11
12
13
14
15
16

17


18
19
20
21
22
23
24
 */

#include "config.h"

#include <string.h>

#import "OFHashes.h"

#import "OFMacros.h"



/*******
 * MD5 *
 *******/

/* The four MD5 core functions - F1 is optimized somewhat */
#define F1(x, y, z) (z ^ (x & (y ^ z)))







>

>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 */

#include "config.h"

#include <string.h>

#import "OFHashes.h"
#import "OFAutoreleasePool.h"
#import "OFMacros.h"

int _OFHashing_reference;

/*******
 * MD5 *
 *******/

/* The four MD5 core functions - F1 is optimized somewhat */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

	/* Handle any remaining bytes of data. */
	memcpy(in, buffer, size);

	return self;
}

- (char*)digest
{
	uint8_t	*p;
	size_t	count;

	if (calculated)
		return (char*)buf;

	/* Compute number of bytes mod 64 */
	count = (bits[0] >> 3) & 0x3F;

	/*
	 * Set the first char of padding to 0x80. This is safe since there is
	 * always at least one byte free







|





|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

	/* Handle any remaining bytes of data. */
	memcpy(in, buffer, size);

	return self;
}

- (uint8_t*)digest
{
	uint8_t	*p;
	size_t	count;

	if (calculated)
		return (uint8_t*)buf;

	/* Compute number of bytes mod 64 */
	count = (bits[0] >> 3) & 0x3F;

	/*
	 * Set the first char of padding to 0x80. This is safe since there is
	 * always at least one byte free
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
	((uint32_t*)in)[15] = bits[1];

	md5_transform(buf, (uint32_t*)in);
	OF_BSWAP_V((uint8_t*)buf, 4);

	calculated = YES;

	return (char*)buf;
}
@end

#undef F1
#undef F2
#undef F3
#undef F4







|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
	((uint32_t*)in)[15] = bits[1];

	md5_transform(buf, (uint32_t*)in);
	OF_BSWAP_V((uint8_t*)buf, 4);

	calculated = YES;

	return (uint8_t*)buf;
}
@end

#undef F1
#undef F2
#undef F3
#undef F4
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
		return self;

	sha1_update(state, &count, buffer, buf, size);

	return self;
}

- (char*)digest
{
	size_t i;
	char   finalcount[8];

	if (calculated)
		return digest;








|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
		return self;

	sha1_update(state, &count, buffer, buf, size);

	return self;
}

- (uint8_t*)digest
{
	size_t i;
	char   finalcount[8];

	if (calculated)
		return digest;

413
414
415
416
417
418
419


























































#undef blk0
#undef blk
#undef R0
#undef R1
#undef R2
#undef R3
#undef R4

































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#undef blk0
#undef blk
#undef R0
#undef R1
#undef R2
#undef R3
#undef R4

@implementation OFString (OFHashing)
- (OFString*)md5Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *hash = [OFMD5Hash md5Hash];
	uint8_t *digest;
	char ret_c[33];
	size_t i;

	[hash updateWithBuffer: string
			ofSize: length];
	digest = [hash digest];

	for (i = 0; i < 16; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		ret_c[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		ret_c[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}
	ret_c[32] = 0;

	[pool release];

	return [OFString stringWithCString: ret_c];
}

- (OFString*)sha1Hash
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *hash = [OFSHA1Hash sha1Hash];
	uint8_t *digest;
	char ret_c[41];
	size_t i;

	[hash updateWithBuffer: string
			ofSize: length];
	digest = [hash digest];

	for (i = 0; i < 20; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		ret_c[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		ret_c[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}
	ret_c[40] = 0;

	[pool release];

	return [OFString stringWithCString: ret_c];
}
@end

Modified src/OFString.h from [292d36265a] to [f69ee67b87].

198
199
200
201
202
203
204

205
206
207
- removeLeadingWhitespaces;
- removeTrailingWhitespaces;
- removeLeadingAndTrailingWhitespaces;
@end

#import "OFConstString.h"
#import "OFMutableString.h"

#import "OFURLEncoding.h"
#import "OFXMLElement.h"
#import "OFXMLParser.h"







>



198
199
200
201
202
203
204
205
206
207
208
- removeLeadingWhitespaces;
- removeTrailingWhitespaces;
- removeLeadingAndTrailingWhitespaces;
@end

#import "OFConstString.h"
#import "OFMutableString.h"
#import "OFHashes.h"
#import "OFURLEncoding.h"
#import "OFXMLElement.h"
#import "OFXMLParser.h"

Modified src/OFString.m from [c4e41efb24] to [7a39667e23].

28
29
30
31
32
33
34

35
36
37
38
39
40
41
#import "OFMacros.h"

#import "asprintf.h"

/* References for static linking */
void _references_to_categories_of_OFString()
{

	_OFURLEncoding_reference = 1;
	_OFXMLElement_reference = 1;
	_OFXMLParser_reference = 1;
};

int
of_string_check_utf8(const char *str, size_t len)







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#import "OFMacros.h"

#import "asprintf.h"

/* References for static linking */
void _references_to_categories_of_OFString()
{
	_OFHashing_reference = 1;
	_OFURLEncoding_reference = 1;
	_OFXMLElement_reference = 1;
	_OFXMLParser_reference = 1;
};

int
of_string_check_utf8(const char *str, size_t len)

Modified tests/OFString/OFString.m from [59018dd6bd] to [a21e69eb00].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#ifndef _WIN32
#define ZD "%zd"
#else
#define ZD "%u"
#endif

#define NUM_TESTS 60
#define SUCCESS								\
	printf("\r\033[1;%dmTests successful: " ZD "/%d\033[0m",	\
	    (i == NUM_TESTS - 1 ? 32 : 33), i + 1, NUM_TESTS);		\
	fflush(stdout);
#define FAIL								\
	printf("\r\033[K\033[1;31mTest " ZD "/%d failed!\033[m\n",	\
	    i + 1, NUM_TESTS);						\







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#ifndef _WIN32
#define ZD "%zd"
#else
#define ZD "%u"
#endif

#define NUM_TESTS 62
#define SUCCESS								\
	printf("\r\033[1;%dmTests successful: " ZD "/%d\033[0m",	\
	    (i == NUM_TESTS - 1 ? 32 : 33), i + 1, NUM_TESTS);		\
	fflush(stdout);
#define FAIL								\
	printf("\r\033[K\033[1;31mTest " ZD "/%d failed!\033[m\n",	\
	    i + 1, NUM_TESTS);						\
149
150
151
152
153
154
155






156
157
158
159
160
161
162
	CHECK([[a objectAtIndex: j++] isEqual: @"foo"])
	CHECK([[a objectAtIndex: j++] isEqual: @"bar"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @"baz"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @""])







	/* URL encoding tests */
	CHECK([[@"foo\"ba'_~$" stringByURLEncoding]
	    isEqual: @"foo%22ba%27_~%24"])
	CHECK([[@"foo%20bar%22+%24" stringByURLDecoding]
	    isEqual: @"foo bar\" $"])
	CHECK_EXCEPT([@"foo%bar" stringByURLDecoding],
	    OFInvalidEncodingException)







>
>
>
>
>
>







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
	CHECK([[a objectAtIndex: j++] isEqual: @"foo"])
	CHECK([[a objectAtIndex: j++] isEqual: @"bar"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @"baz"])
	CHECK([[a objectAtIndex: j++] isEqual: @""])
	CHECK([[a objectAtIndex: j++] isEqual: @""])

	/* Hash tests */
	CHECK([[@"asdfoobar" md5Hash]
	    isEqual: @"184dce2ec49b5422c7cfd8728864db4c"]);
	CHECK([[@"asdfoobar" sha1Hash]
	    isEqual: @"f5f81ac0a8b5cbfdc4585ec1ad32e7b3a12b9b49"]);

	/* URL encoding tests */
	CHECK([[@"foo\"ba'_~$" stringByURLEncoding]
	    isEqual: @"foo%22ba%27_~%24"])
	CHECK([[@"foo%20bar%22+%24" stringByURLDecoding]
	    isEqual: @"foo bar\" $"])
	CHECK_EXCEPT([@"foo%bar" stringByURLDecoding],
	    OFInvalidEncodingException)