ObjFW  Check-in [75f2aa5096]

Overview
Comment:Clean up OFHash and the Hashing categories.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 75f2aa50965d2f9c258815081223a81ae264b4185abc34142d168c3133fa9713
User & Date: js on 2013-12-08 17:43:19
Other Links: manifest | tags
Context
2013-12-09
22:07
Fix createSymbolicLinkAtPath:withDestinationPath:. check-in: ba2b4661de user: js tags: trunk
2013-12-08
17:43
Clean up OFHash and the Hashing categories. check-in: 75f2aa5096 user: js tags: trunk
2013-12-07
17:30
macros.h: Add OF_BIGGEST_ALIGNMENT. check-in: fdfb2be253 user: js tags: trunk
Changes

Modified src/OFDataArray+Hashing.m from [2171c1b800] to [4c3a34c5e7].

14
15
16
17
18
19
20

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

33
34
35
36
37
38
39
40
41
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 * file.
 */

#include "config.h"

#import "OFDataArray.h"
#import "OFString.h"

#import "OFMD5Hash.h"
#import "OFSHA1Hash.h"

#import "autorelease.h"

int _OFDataArray_Hashing_reference;

@implementation OFDataArray (Hashing)
- (OFString*)MD5Hash
{
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *hash = [OFMD5Hash hash];

	uint8_t *digest;
	char cString[OF_MD5_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: _items
			length: _count * _itemSize];
	digest = [hash digest];

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

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

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

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: OF_MD5_DIGEST_SIZE * 2];
}

- (OFString*)SHA1Hash
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA1Hash *hash = [OFSHA1Hash hash];
	uint8_t *digest;
	char cString[OF_SHA1_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: _items
			length: _count * _itemSize];
	digest = [hash digest];

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

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

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

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: OF_SHA1_DIGEST_SIZE * 2];
}
@end







>








|


|
>
|
|






|













|


|

<
<
<
<
<
|
<
<
<
|
<
<

<
<
|
<
<
<
|
<
|
<
<
<


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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



68
69
 * file.
 */

#include "config.h"

#import "OFDataArray.h"
#import "OFString.h"
#import "OFHash.h"
#import "OFMD5Hash.h"
#import "OFSHA1Hash.h"

#import "autorelease.h"

int _OFDataArray_Hashing_reference;

@implementation OFDataArray (Hashing)
- (OFString*)OF_hashAsStringWithHash: (Class <OFHash>)hashClass
{
	void *pool = objc_autoreleasePoolPush();
	id <OFHash> hash = [hashClass hash];
	size_t digestSize = [hashClass digestSize];
	const uint8_t *digest;
	char cString[digestSize * 2];
	size_t i;

	[hash updateWithBuffer: _items
			length: _count * _itemSize];
	digest = [hash digest];

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

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

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

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString*)MD5Hash
{





	return [self OF_hashAsStringWithHash: [OFMD5Hash class]];



}





- (OFString*)SHA1Hash



{

	return [self OF_hashAsStringWithHash: [OFSHA1Hash class]];



}
@end

Modified src/OFHash.h from [ecafca2322] to [660b2e2817].

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 * @brief Returns a buffer containing the hash.
 *
 * The size of the buffer depends on the hash used. The buffer is part of the
 * receiver's memory pool.
 *
 * @return A buffer containing the hash
 */
- (uint8_t*)digest OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns a boolean whether the hash has already been calculated.
 *
 * @return A boolean whether the hash has already been calculated
 */
- (bool)isCalculated;
@end







|








58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 * @brief Returns a buffer containing the hash.
 *
 * The size of the buffer depends on the hash used. The buffer is part of the
 * receiver's memory pool.
 *
 * @return A buffer containing the hash
 */
- (const uint8_t*)digest OF_RETURNS_INNER_POINTER;

/*!
 * @brief Returns a boolean whether the hash has already been calculated.
 *
 * @return A boolean whether the hash has already been calculated
 */
- (bool)isCalculated;
@end

Modified src/OFMD5Hash.h from [fea508e8e7] to [795e2e7102].

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFHash.h"

#define OF_MD5_DIGEST_SIZE 16

/*!
 * @brief A class which provides functions to create an MD5 hash.
 */
@interface OFMD5Hash: OFObject <OFHash>
{
	uint32_t _buffer[4];
	uint32_t _bits[2];







<
<







12
13
14
15
16
17
18


19
20
21
22
23
24
25
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFHash.h"



/*!
 * @brief A class which provides functions to create an MD5 hash.
 */
@interface OFMD5Hash: OFObject <OFHash>
{
	uint32_t _buffer[4];
	uint32_t _bits[2];

Modified src/OFMD5Hash.m from [ae6cec6554] to [ffb1eddc7f].

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
		length -= 64;
	}

	/* Handle any remaining bytes of data. */
	memcpy(_in.u8, buffer, length);
}

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

	if (_calculated)
		return (uint8_t*)_buffer;








|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
		length -= 64;
	}

	/* Handle any remaining bytes of data. */
	memcpy(_in.u8, buffer, length);
}

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

	if (_calculated)
		return (uint8_t*)_buffer;

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
	_in.u32[15] = _bits[1];

	md5_transform(_buffer, _in.u32);
	BSWAP32_VEC_IF_BE(_buffer, 4);

	_calculated = true;

	return (uint8_t*)_buffer;
}

- (bool)isCalculated
{
	return _calculated;
}
@end







|







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
	_in.u32[15] = _bits[1];

	md5_transform(_buffer, _in.u32);
	BSWAP32_VEC_IF_BE(_buffer, 4);

	_calculated = true;

	return (const uint8_t*)_buffer;
}

- (bool)isCalculated
{
	return _calculated;
}
@end

Modified src/OFSHA1Hash.h from [88105141d2] to [4ec040338d].

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFHash.h"

#define OF_SHA1_DIGEST_SIZE 20

/*!
 * @brief A class which provides functions to create an SHA1 hash.
 */
@interface OFSHA1Hash: OFObject <OFHash>
{
	uint32_t _state[5];
	uint64_t _count;
	char	 _buffer[64];
	uint8_t	 _digest[OF_SHA1_DIGEST_SIZE];
	bool	 _calculated;
}
@end







<
<








|



12
13
14
15
16
17
18


19
20
21
22
23
24
25
26
27
28
29
30
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFHash.h"



/*!
 * @brief A class which provides functions to create an SHA1 hash.
 */
@interface OFSHA1Hash: OFObject <OFHash>
{
	uint32_t _state[5];
	uint64_t _count;
	char	 _buffer[64];
	uint8_t	 _digest[20];
	bool	 _calculated;
}
@end

Modified src/OFSHA1Hash.m from [0b7be48688] to [4f0ad14fda].

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithHash: self];

	sha1_update(_state, &_count, _buffer, buffer, length);
}

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

	if (_calculated)
		return _digest;

	for (i = 0; i < 8; i++)
		/* Endian independent */
		finalcount[i] = (char)((_count >> ((7 - (i & 7)) * 8)) & 255);
	sha1_update(_state, &_count, _buffer, "\200", 1);

	while ((_count & 504) != 448)
		sha1_update(_state, &_count, _buffer, "\0", 1);
	/* Should cause a sha1_transform() */
	sha1_update(_state, &_count, _buffer, finalcount, 8);

	for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++)
		_digest[i] = (char)((_state[i >> 2] >>
		    ((3 - (i & 3)) * 8)) & 255);

	_calculated = true;

	return _digest;
}

- (bool)isCalculated
{
	return _calculated;
}
@end







|

















|













166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
	if (_calculated)
		@throw [OFHashAlreadyCalculatedException
		    exceptionWithHash: self];

	sha1_update(_state, &_count, _buffer, buffer, length);
}

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

	if (_calculated)
		return _digest;

	for (i = 0; i < 8; i++)
		/* Endian independent */
		finalcount[i] = (char)((_count >> ((7 - (i & 7)) * 8)) & 255);
	sha1_update(_state, &_count, _buffer, "\200", 1);

	while ((_count & 504) != 448)
		sha1_update(_state, &_count, _buffer, "\0", 1);
	/* Should cause a sha1_transform() */
	sha1_update(_state, &_count, _buffer, finalcount, 8);

	for (i = 0; i < 20; i++)
		_digest[i] = (char)((_state[i >> 2] >>
		    ((3 - (i & 3)) * 8)) & 255);

	_calculated = true;

	return _digest;
}

- (bool)isCalculated
{
	return _calculated;
}
@end

Modified src/OFString+Hashing.m from [19f8d7a88b] to [903e063a45].

13
14
15
16
17
18
19

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

32
33
34
35
36
37
38
39
40
41
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFString.h"

#import "OFMD5Hash.h"
#import "OFSHA1Hash.h"

#import "autorelease.h"

int _OFString_Hashing_reference;

@implementation OFString (Hashing)
- (OFString*)MD5Hash
{
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *hash = [OFMD5Hash hash];

	uint8_t *digest;
	char ret[OF_MD5_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: [self UTF8String]
			length: [self UTF8StringLength]];
	digest = [hash digest];

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

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

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

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: ret
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 32];
}

- (OFString*)SHA1Hash
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA1Hash *hash = [OFSHA1Hash hash];
	uint8_t *digest;
	char ret[OF_SHA1_DIGEST_SIZE * 2];
	size_t i;

	[hash updateWithBuffer: [self UTF8String]
			length: [self UTF8StringLength]];
	digest = [hash digest];

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

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

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

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: ret
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 40];
}
@end







>








|


|
>
|
|






|





|
|




|

|


|

<
<
<
<
<
|
<
<
<
|
<
<

<
<
|
<
<
<
|
<
|
<
<
<


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
68
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFString.h"
#import "OFHash.h"
#import "OFMD5Hash.h"
#import "OFSHA1Hash.h"

#import "autorelease.h"

int _OFString_Hashing_reference;

@implementation OFString (Hashing)
- (OFString*)OF_hashAsStringWithHash: (Class <OFHash>)hashClass
{
	void *pool = objc_autoreleasePoolPush();
	id <OFHash> hash = [hashClass hash];
	size_t digestSize = [hashClass digestSize];
	const uint8_t *digest;
	char cString[digestSize * 2];
	size_t i;

	[hash updateWithBuffer: [self UTF8String]
			length: [self UTF8StringLength]];
	digest = [hash digest];

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

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

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

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString*)MD5Hash
{





	return [self OF_hashAsStringWithHash: [OFMD5Hash class]];



}





- (OFString*)SHA1Hash



{

	return [self OF_hashAsStringWithHash: [OFSHA1Hash class]];



}
@end

Modified tests/OFMD5HashTests.m from [33fe966ada] to [4481969842].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#import "OFHashAlreadyCalculatedException.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFMD5Hash";

const uint8_t testfile_md5[OF_MD5_DIGEST_SIZE] =
	"\x00\x8B\x9D\x1B\x58\xDF\xF8\xFE\xEE\xF3\xAE\x8D\xBB\x68\x2D\x38";

@implementation TestsAppDelegate (OFMD5HashTests)
- (void)MD5HashTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *md5;







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#import "OFHashAlreadyCalculatedException.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFMD5Hash";

const uint8_t testfile_md5[16] =
	"\x00\x8B\x9D\x1B\x58\xDF\xF8\xFE\xEE\xF3\xAE\x8D\xBB\x68\x2D\x38";

@implementation TestsAppDelegate (OFMD5HashTests)
- (void)MD5HashTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMD5Hash *md5;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[md5 updateWithBuffer: buf
			       length: len];
	}
	[f close];

	TEST(@"-[digest]",
	    !memcmp([md5 digest], testfile_md5, OF_MD5_DIGEST_SIZE))

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length]", OFHashAlreadyCalculatedException,
	    [md5 updateWithBuffer: ""
			   length: 1])

	[pool drain];
}
@end







|
<









47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[md5 updateWithBuffer: buf
			       length: len];
	}
	[f close];

	TEST(@"-[digest]", !memcmp([md5 digest], testfile_md5, 16))


	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length]", OFHashAlreadyCalculatedException,
	    [md5 updateWithBuffer: ""
			   length: 1])

	[pool drain];
}
@end

Modified tests/OFSHA1HashTests.m from [2d11f0346d] to [90393e26d2].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#import "OFHashAlreadyCalculatedException.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFHash";

const uint8_t testfile_sha1[OF_SHA1_DIGEST_SIZE] =
	"\xC9\x9A\xB8\x7E\x1E\xC8\xEC\x65\xD5\xEB\xE4\x2E\x0D\xA6\x80\x96\xF5"
	"\x94\xE7\x17";

@implementation TestsAppDelegate (SHA1HashTests)
- (void)SHA1HashTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];







|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#import "OFHashAlreadyCalculatedException.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFHash";

const uint8_t testfile_sha1[20] =
	"\xC9\x9A\xB8\x7E\x1E\xC8\xEC\x65\xD5\xEB\xE4\x2E\x0D\xA6\x80\x96\xF5"
	"\x94\xE7\x17";

@implementation TestsAppDelegate (SHA1HashTests)
- (void)SHA1HashTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[sha1 updateWithBuffer: buf
				length: len];
	}
	[f close];

	TEST(@"-[digest]",
	    !memcmp([sha1 digest], testfile_sha1, OF_SHA1_DIGEST_SIZE))

	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha1 updateWithBuffer: ""
			    length: 1])

	[pool drain];
}
@end







|
<









48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
		size_t len = [f readIntoBuffer: buf
					length: 64];
		[sha1 updateWithBuffer: buf
				length: len];
	}
	[f close];

	TEST(@"-[digest]", !memcmp([sha1 digest], testfile_sha1, 20))


	EXPECT_EXCEPTION(@"Detect invalid call of "
	    @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException,
	    [sha1 updateWithBuffer: ""
			    length: 1])

	[pool drain];
}
@end