root / pithos-macos / HashMapHash.m @ 75cecfcc
History | View | Annotate | Download (5.9 kB)
1 | f2f50f78 | Miltiadis Vasilakis | // |
---|---|---|---|
2 | f2f50f78 | Miltiadis Vasilakis | // HashMapHash.m |
3 | f2f50f78 | Miltiadis Vasilakis | // pithos-macos |
4 | f2f50f78 | Miltiadis Vasilakis | // |
5 | f2f50f78 | Miltiadis Vasilakis | // Copyright 2011 GRNET S.A. All rights reserved. |
6 | f2f50f78 | Miltiadis Vasilakis | // |
7 | f2f50f78 | Miltiadis Vasilakis | // Redistribution and use in source and binary forms, with or |
8 | f2f50f78 | Miltiadis Vasilakis | // without modification, are permitted provided that the following |
9 | f2f50f78 | Miltiadis Vasilakis | // conditions are met: |
10 | f2f50f78 | Miltiadis Vasilakis | // |
11 | f2f50f78 | Miltiadis Vasilakis | // 1. Redistributions of source code must retain the above |
12 | f2f50f78 | Miltiadis Vasilakis | // copyright notice, this list of conditions and the following |
13 | f2f50f78 | Miltiadis Vasilakis | // disclaimer. |
14 | f2f50f78 | Miltiadis Vasilakis | // |
15 | f2f50f78 | Miltiadis Vasilakis | // 2. Redistributions in binary form must reproduce the above |
16 | f2f50f78 | Miltiadis Vasilakis | // copyright notice, this list of conditions and the following |
17 | f2f50f78 | Miltiadis Vasilakis | // disclaimer in the documentation and/or other materials |
18 | f2f50f78 | Miltiadis Vasilakis | // provided with the distribution. |
19 | f2f50f78 | Miltiadis Vasilakis | // |
20 | f2f50f78 | Miltiadis Vasilakis | // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
21 | f2f50f78 | Miltiadis Vasilakis | // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
22 | f2f50f78 | Miltiadis Vasilakis | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | f2f50f78 | Miltiadis Vasilakis | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
24 | f2f50f78 | Miltiadis Vasilakis | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
25 | f2f50f78 | Miltiadis Vasilakis | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
26 | f2f50f78 | Miltiadis Vasilakis | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
27 | f2f50f78 | Miltiadis Vasilakis | // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
28 | f2f50f78 | Miltiadis Vasilakis | // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 | f2f50f78 | Miltiadis Vasilakis | // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
30 | f2f50f78 | Miltiadis Vasilakis | // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 | f2f50f78 | Miltiadis Vasilakis | // POSSIBILITY OF SUCH DAMAGE. |
32 | f2f50f78 | Miltiadis Vasilakis | // |
33 | f2f50f78 | Miltiadis Vasilakis | // The views and conclusions contained in the software and |
34 | f2f50f78 | Miltiadis Vasilakis | // documentation are those of the authors and should not be |
35 | f2f50f78 | Miltiadis Vasilakis | // interpreted as representing official policies, either expressed |
36 | f2f50f78 | Miltiadis Vasilakis | // or implied, of GRNET S.A. |
37 | f2f50f78 | Miltiadis Vasilakis | |
38 | f2f50f78 | Miltiadis Vasilakis | #import "HashMapHash.h" |
39 | f2f50f78 | Miltiadis Vasilakis | #import <CommonCrypto/CommonHMAC.h> |
40 | f2f50f78 | Miltiadis Vasilakis | |
41 | f2f50f78 | Miltiadis Vasilakis | @implementation HashMapHash |
42 | f2f50f78 | Miltiadis Vasilakis | |
43 | f2f50f78 | Miltiadis Vasilakis | + (NSString *)calculateHashMapHash:(NSArray *)hashes { |
44 | f2f50f78 | Miltiadis Vasilakis | const char padding[] = { |
45 | f2f50f78 | Miltiadis Vasilakis | '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', |
46 | f2f50f78 | Miltiadis Vasilakis | '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'}; |
47 | f2f50f78 | Miltiadis Vasilakis | |
48 | f2f50f78 | Miltiadis Vasilakis | if ([hashes count] == 0) |
49 | f2f50f78 | Miltiadis Vasilakis | return [HashMapHash formatHash:[HashMapHash calculateHash:[NSData dataWithBytes:padding length:0]]]; |
50 | f2f50f78 | Miltiadis Vasilakis | if ([hashes count] == 1) |
51 | 1284948f | Miltiadis Vasilakis | return [HashMapHash formatHash:[hashes objectAtIndex:0]]; |
52 | f2f50f78 | Miltiadis Vasilakis | |
53 | f2f50f78 | Miltiadis Vasilakis | int s = 2; |
54 | f2f50f78 | Miltiadis Vasilakis | while (s < [hashes count]) |
55 | f2f50f78 | Miltiadis Vasilakis | s = s * 2; |
56 | f2f50f78 | Miltiadis Vasilakis | |
57 | f2f50f78 | Miltiadis Vasilakis | NSMutableArray *h = [NSMutableArray array]; |
58 | f2f50f78 | Miltiadis Vasilakis | for (int i = 0; i < [hashes count]; i++) |
59 | 1284948f | Miltiadis Vasilakis | [h addObject:[hashes objectAtIndex:i]]; |
60 | f2f50f78 | Miltiadis Vasilakis | for (int i = 0; i < s - [hashes count]; i++) |
61 | 1284948f | Miltiadis Vasilakis | [h addObject:[NSMutableData dataWithBytes:padding length:32]]; |
62 | f2f50f78 | Miltiadis Vasilakis | |
63 | f2f50f78 | Miltiadis Vasilakis | while ([h count] > 1) { |
64 | f2f50f78 | Miltiadis Vasilakis | for (int i = 0; i < [h count]; i = i + 2) { |
65 | f2f50f78 | Miltiadis Vasilakis | NSMutableData *bytesData = [h objectAtIndex:i]; |
66 | f2f50f78 | Miltiadis Vasilakis | [bytesData appendData:[h objectAtIndex:i + 1]]; |
67 | f2f50f78 | Miltiadis Vasilakis | [h replaceObjectAtIndex:i withObject:[HashMapHash calculateHash:bytesData]]; |
68 | f2f50f78 | Miltiadis Vasilakis | } |
69 | f2f50f78 | Miltiadis Vasilakis | |
70 | f2f50f78 | Miltiadis Vasilakis | NSMutableIndexSet *indicesToRemove = [NSMutableIndexSet indexSet]; |
71 | 1284948f | Miltiadis Vasilakis | for (int i = 0; i < [h count]; i = i + 2) |
72 | f2f50f78 | Miltiadis Vasilakis | [indicesToRemove addIndex:i + 1]; |
73 | 1284948f | Miltiadis Vasilakis | |
74 | f2f50f78 | Miltiadis Vasilakis | [h removeObjectsAtIndexes:indicesToRemove]; |
75 | f2f50f78 | Miltiadis Vasilakis | } |
76 | f2f50f78 | Miltiadis Vasilakis | return [HashMapHash formatHash:[h objectAtIndex:0]]; |
77 | f2f50f78 | Miltiadis Vasilakis | } |
78 | f2f50f78 | Miltiadis Vasilakis | |
79 | f2f50f78 | Miltiadis Vasilakis | + (NSData *)calculateHash:(NSData *)data { |
80 | f2f50f78 | Miltiadis Vasilakis | unsigned char hash[CC_SHA256_DIGEST_LENGTH]; |
81 | f2f50f78 | Miltiadis Vasilakis | CC_SHA256([data bytes], (unsigned int)[data length], hash); |
82 | f2f50f78 | Miltiadis Vasilakis | return [NSMutableData dataWithBytes:hash length:CC_SHA256_DIGEST_LENGTH]; |
83 | f2f50f78 | Miltiadis Vasilakis | } |
84 | f2f50f78 | Miltiadis Vasilakis | |
85 | f2f50f78 | Miltiadis Vasilakis | + (NSString *)formatHash:(NSData *)data { |
86 | f2f50f78 | Miltiadis Vasilakis | NSString *hashString; |
87 | f2f50f78 | Miltiadis Vasilakis | hashString = [NSString stringWithFormat:@"%@", data]; |
88 | f2f50f78 | Miltiadis Vasilakis | hashString = [hashString stringByReplacingOccurrencesOfString:@" " withString:@""]; |
89 | f2f50f78 | Miltiadis Vasilakis | hashString = [hashString stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; |
90 | f2f50f78 | Miltiadis Vasilakis | return hashString; |
91 | f2f50f78 | Miltiadis Vasilakis | } |
92 | f2f50f78 | Miltiadis Vasilakis | |
93 | f2f50f78 | Miltiadis Vasilakis | // XXX hardcoded hash algorithm for now |
94 | f2f50f78 | Miltiadis Vasilakis | + (NSArray *)calculateObjectHashMap:(NSString *)filePath withBlockHash:(NSString *)blockHash andBlockSize:(NSUInteger)blockSize { |
95 | f2f50f78 | Miltiadis Vasilakis | NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:filePath]; |
96 | f2f50f78 | Miltiadis Vasilakis | if (fh == nil) { |
97 | f2f50f78 | Miltiadis Vasilakis | NSLog(@"failed to open file: %@", filePath); |
98 | f2f50f78 | Miltiadis Vasilakis | return nil; |
99 | f2f50f78 | Miltiadis Vasilakis | } |
100 | f2f50f78 | Miltiadis Vasilakis | |
101 | f2f50f78 | Miltiadis Vasilakis | NSFileManager *fm = [NSFileManager defaultManager]; |
102 | f2f50f78 | Miltiadis Vasilakis | NSDictionary *attributes = [fm attributesOfItemAtPath:filePath error:nil]; |
103 | f2f50f78 | Miltiadis Vasilakis | NSUInteger endOfFile = [attributes fileSize]; |
104 | f2f50f78 | Miltiadis Vasilakis | |
105 | f2f50f78 | Miltiadis Vasilakis | NSUInteger fileOffset = 0; |
106 | f2f50f78 | Miltiadis Vasilakis | [fh seekToFileOffset:fileOffset]; |
107 | f2f50f78 | Miltiadis Vasilakis | |
108 | f2f50f78 | Miltiadis Vasilakis | NSMutableArray *hashes = [[[NSMutableArray alloc] init] autorelease]; |
109 | f2f50f78 | Miltiadis Vasilakis | |
110 | f2f50f78 | Miltiadis Vasilakis | while(fileOffset < endOfFile){ |
111 | f2f50f78 | Miltiadis Vasilakis | NSData *data = [fh readDataOfLength:blockSize]; |
112 | f2f50f78 | Miltiadis Vasilakis | |
113 | f2f50f78 | Miltiadis Vasilakis | // Strip trailing slashes. |
114 | f2f50f78 | Miltiadis Vasilakis | const char *bytes = [data bytes]; |
115 | f2f50f78 | Miltiadis Vasilakis | NSInteger i; |
116 | f2f50f78 | Miltiadis Vasilakis | for (i = [data length] - 1; i >= 0; i--) |
117 | f2f50f78 | Miltiadis Vasilakis | if (bytes[i] != '\0') |
118 | f2f50f78 | Miltiadis Vasilakis | break; |
119 | 572efb9e | Miltiadis Vasilakis | if (i != [data length] - 1) { |
120 | 572efb9e | Miltiadis Vasilakis | if (i >= 0) |
121 | 572efb9e | Miltiadis Vasilakis | data = [data subdataWithRange:NSMakeRange(0, i + 1)]; |
122 | 572efb9e | Miltiadis Vasilakis | else |
123 | 572efb9e | Miltiadis Vasilakis | data = [NSData data]; |
124 | 572efb9e | Miltiadis Vasilakis | } |
125 | f2f50f78 | Miltiadis Vasilakis | |
126 | f2f50f78 | Miltiadis Vasilakis | unsigned char hash[CC_SHA256_DIGEST_LENGTH]; |
127 | f2f50f78 | Miltiadis Vasilakis | |
128 | f2f50f78 | Miltiadis Vasilakis | if ( CC_SHA256([data bytes], (unsigned int)[data length], hash) ) { |
129 | 1284948f | Miltiadis Vasilakis | NSData *sha256 = [NSMutableData dataWithBytes:hash length:CC_SHA256_DIGEST_LENGTH]; |
130 | 1284948f | Miltiadis Vasilakis | [hashes addObject:sha256]; |
131 | f2f50f78 | Miltiadis Vasilakis | } |
132 | f2f50f78 | Miltiadis Vasilakis | |
133 | f2f50f78 | Miltiadis Vasilakis | fileOffset += blockSize; |
134 | f2f50f78 | Miltiadis Vasilakis | [fh seekToFileOffset:fileOffset]; |
135 | f2f50f78 | Miltiadis Vasilakis | } |
136 | f2f50f78 | Miltiadis Vasilakis | |
137 | f2f50f78 | Miltiadis Vasilakis | [fh closeFile]; |
138 | f2f50f78 | Miltiadis Vasilakis | |
139 | f2f50f78 | Miltiadis Vasilakis | NSArray *hashMap = [NSArray arrayWithArray:hashes]; |
140 | f2f50f78 | Miltiadis Vasilakis | |
141 | f2f50f78 | Miltiadis Vasilakis | return hashMap; |
142 | f2f50f78 | Miltiadis Vasilakis | } |
143 | f2f50f78 | Miltiadis Vasilakis | |
144 | 1284948f | Miltiadis Vasilakis | + (NSArray *)objectHashMapStrings:(NSString *)filePath withBlockHash:(NSString *)blockHash andBlockSize:(NSUInteger)blockSize { |
145 | 1284948f | Miltiadis Vasilakis | NSArray *hashHexes = [HashMapHash calculateObjectHashMap:filePath withBlockHash:blockHash andBlockSize:blockSize]; |
146 | 1284948f | Miltiadis Vasilakis | if (hashHexes == nil) |
147 | 1284948f | Miltiadis Vasilakis | return nil; |
148 | 1284948f | Miltiadis Vasilakis | |
149 | 1284948f | Miltiadis Vasilakis | NSMutableArray *hashStrings = [[[NSMutableArray alloc] init] autorelease]; |
150 | 1284948f | Miltiadis Vasilakis | |
151 | 1284948f | Miltiadis Vasilakis | for (NSData *hashHex in hashHexes) { |
152 | 1284948f | Miltiadis Vasilakis | [hashStrings addObject:[HashMapHash formatHash:hashHex]]; |
153 | 1284948f | Miltiadis Vasilakis | } |
154 | 1284948f | Miltiadis Vasilakis | |
155 | 1284948f | Miltiadis Vasilakis | NSArray *hashMap = [NSArray arrayWithArray:hashStrings]; |
156 | 1284948f | Miltiadis Vasilakis | return hashMap; |
157 | 1284948f | Miltiadis Vasilakis | } |
158 | 1284948f | Miltiadis Vasilakis | |
159 | f2f50f78 | Miltiadis Vasilakis | @end |