Jelajahi Sumber

Hash return [UInt8] in place of NSData

Marcin Krzyżanowski 10 tahun lalu
induk
melakukan
736325d33e

+ 2 - 8
CryptoSwift/CRC.swift

@@ -43,7 +43,7 @@ final class CRC {
         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
         0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d]
     
-    func crc32(message:NSData) -> NSData {
+    func crc32(message:NSData) -> UInt32 {
         var crc:UInt32 = 0xffffffff
         
         for chunk in NSDataSequence(chunkSize: 256, data: message) {
@@ -53,12 +53,6 @@ final class CRC {
             }
         }
         
-        crc = crc ^ 0xffffffff
-        
-        // reverse bytes
-        let bytes = Array(NSMutableData(bytes: &crc, length: 4).arrayOfBytes().reverse()) //FIXME: Array ??
-        let data = NSData(bytes: bytes, length: bytes.count)
-        return data
+        return crc ^ 0xffffffff
     }
-    
 }

+ 2 - 2
CryptoSwift/Hash.swift

@@ -14,7 +14,7 @@ public enum Hash {
     case sha224(NSData), sha256(NSData), sha384(NSData), sha512(NSData)
     case crc32(NSData)
     
-    public func calculate() -> NSData? {
+    public func calculate() -> [UInt8]? {
         switch self {
         case md5(let data):
             return MD5(data).calculate()
@@ -29,7 +29,7 @@ public enum Hash {
         case sha512(let data):
             return SHA2(data, variant: .sha512).calculate64()
         case crc32(let data):
-            return CRC().crc32(data);
+            return CRC().crc32(data).bytes()
         }
     }
 }

+ 8 - 7
CryptoSwift/MD5.swift

@@ -42,7 +42,7 @@ final class MD5 : HashProtocol  {
     
     private let h:[UInt32] = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]
     
-    func calculate() -> NSData {
+    func calculate() -> [UInt8] {
         let tmpMessage = prepare(64)
 
         // hash values
@@ -107,13 +107,14 @@ final class MD5 : HashProtocol  {
             hh[3] = hh[3] &+ D
         }
 
-        let buf: NSMutableData = NSMutableData();
-        hh.forEach({ (item) -> () in
-            var i:UInt32 = item.littleEndian
-            buf.appendBytes(&i, length: sizeofValue(i))
-        })
+        var result = [UInt8]()
+        result.reserveCapacity(hh.count / 4)
         
-        return buf.copy() as! NSData
+        hh.forEach {
+            let itemLE = $0.littleEndian
+            result += [UInt8(itemLE & 0xff), UInt8((itemLE >> 8) & 0xff), UInt8((itemLE >> 16) & 0xff), UInt8((itemLE >> 24) & 0xff)]
+        }
+        return result
     }
 }
 

+ 18 - 13
CryptoSwift/NSDataExtension.swift

@@ -19,45 +19,50 @@ extension NSMutableData {
 
 extension NSData {
 
+    /// Two octet checksum as defined in RFC-4880. Sum of all octets, mod 65536
     public func checksum() -> UInt16 {
-        var s:UInt32 = 0;
-        
+        var s:UInt32 = 0
         var bytesArray = self.arrayOfBytes()
-        
         for (var i = 0; i < bytesArray.count; i++) {
-            _ = bytesArray[i]
             s = s + UInt32(bytesArray[i])
         }
-        s = s % 65536;
-        return UInt16(s);
+        s = s % 65536
+        return UInt16(s)
     }
     
     public func md5() -> NSData? {
-        return Hash.md5(self).calculate()
+        guard let result = Hash.md5(self).calculate() else { return nil }
+        return NSData.withBytes(result)
     }
 
     public func sha1() -> NSData? {
-        return Hash.sha1(self).calculate()
+        guard let result = Hash.sha1(self).calculate() else { return nil }
+        return NSData.withBytes(result)
     }
 
     public func sha224() -> NSData? {
-        return Hash.sha224(self).calculate()
+        guard let result = Hash.sha224(self).calculate() else { return nil }
+        return NSData.withBytes(result)
     }
 
     public func sha256() -> NSData? {
-        return Hash.sha256(self).calculate()
+        guard let result = Hash.sha256(self).calculate() else { return nil }
+        return NSData.withBytes(result)
     }
 
     public func sha384() -> NSData? {
-        return Hash.sha384(self).calculate()
+        guard let result = Hash.sha384(self).calculate() else { return nil }
+        return NSData.withBytes(result)
     }
 
     public func sha512() -> NSData? {
-        return Hash.sha512(self).calculate()
+        guard let result = Hash.sha512(self).calculate() else { return nil }
+        return NSData.withBytes(result)
     }
 
     public func crc32() -> NSData? {
-        return Hash.crc32(self).calculate()
+        guard let result = Hash.crc32(self).calculate() else { return nil }
+        return NSData.withBytes(result)
     }
 
     public func encrypt(cipher: Cipher) throws -> NSData? {

+ 8 - 8
CryptoSwift/SHA1.swift

@@ -18,7 +18,7 @@ final class SHA1 : HashProtocol {
     
     private let h:[UInt32] = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
         
-    func calculate() -> NSData {
+    func calculate() -> [UInt8] {
         let tmpMessage = self.prepare(64)
         
         // hash values
@@ -94,12 +94,12 @@ final class SHA1 : HashProtocol {
         }
         
         // Produce the final hash value (big-endian) as a 160 bit number:
-        let buf: NSMutableData = NSMutableData();
-        for item in hh {
-            var i:UInt32 = item.bigEndian
-            buf.appendBytes(&i, length: sizeofValue(i))
+        var result = [UInt8]()
+        result.reserveCapacity(hh.count / 4)
+        hh.forEach {
+            let item = $0.bigEndian
+            result += [UInt8(item & 0xff), UInt8((item >> 8) & 0xff), UInt8((item >> 16) & 0xff), UInt8((item >> 24) & 0xff)]
         }
-        
-        return buf.copy() as! NSData;
-    }    
+        return result
+    }
 }

+ 20 - 23
CryptoSwift/SHA2.swift

@@ -102,24 +102,21 @@ final class SHA2 : HashProtocol {
             }
         }
         
-        private func resultingArray<T>(hh:[T]) -> [T] {
-            var finalHH:[T] = hh;
+        private func resultingArray<T>(hh:[T]) -> ArraySlice<T> {
             switch (self) {
             case .sha224:
-                finalHH = Array(hh[0..<7])
-                break;
+                return hh[0..<7]
             case .sha384:
-                finalHH = Array(hh[0..<6])
-                break;
+                return hh[0..<6]
             default:
                 break;
             }
-            return finalHH
+            return ArraySlice(hh)
         }
     }
     
     //FIXME: I can't do Generic func out of calculate32 and calculate64 (UInt32 vs UInt64), but if you can - please do pull request.
-    func calculate32() -> NSData {
+    func calculate32() -> [UInt8] {
         let tmpMessage = self.prepare(64)
         
         // hash values
@@ -191,16 +188,16 @@ final class SHA2 : HashProtocol {
         }
         
         // Produce the final hash value (big-endian) as a 160 bit number:
-        let buf: NSMutableData = NSMutableData();
-        variant.resultingArray(hh).forEach{ (item) -> () in
-            var i:UInt32 = UInt32(item.bigEndian)
-            buf.appendBytes(&i, length: sizeofValue(i))
+        var result = [UInt8]()
+        result.reserveCapacity(hh.count / 4)
+        variant.resultingArray(hh).forEach {
+            let item = $0.bigEndian
+            result += [UInt8(item & 0xff), UInt8((item >> 8) & 0xff), UInt8((item >> 16) & 0xff), UInt8((item >> 24) & 0xff)]
         }
-		
-        return buf.copy() as! NSData;
+        return result
     }
     
-    func calculate64() -> NSData {
+    func calculate64() -> [UInt8] {
         let tmpMessage = self.prepare(128)
         
         // hash values
@@ -275,13 +272,13 @@ final class SHA2 : HashProtocol {
         }
         
         // Produce the final hash value (big-endian)
-        let buf: NSMutableData = NSMutableData();
-        
-        variant.resultingArray(hh).forEach({ (item) -> () in
-            var i = item.bigEndian
-            buf.appendBytes(&i, length: sizeofValue(i))
-        })
-        
-        return buf.copy() as! NSData;
+        var result = [UInt8]()
+        result.reserveCapacity(hh.count / 4)
+        variant.resultingArray(hh).forEach {
+            let item = $0.bigEndian
+            result += [UInt8(item & 0xff), UInt8((item >> 8) & 0xff), UInt8((item >> 16) & 0xff), UInt8((item >> 24) & 0xff),
+                       UInt8((item >> 32) & 0xff),UInt8((item >> 40) & 0xff), UInt8((item >> 48) & 0xff), UInt8((item >> 56) & 0xff)]
+        }
+        return result
     }
 }

+ 6 - 12
CryptoSwiftTests/HashTests.swift

@@ -22,7 +22,7 @@ final class CryptoSwiftTests: XCTestCase {
     func testMD5() {
         let data1:NSData = NSData(bytes: [0x31, 0x32, 0x33] as [UInt8], length: 3) // "1", "2", "3"
         if let hash = Hash.md5(data1).calculate() {
-            XCTAssertEqual(hash.toHexString(), "202cb962ac59075b964b07152d234b70", "MD5 calculation failed");
+            XCTAssertEqual(hash, [0x20,0x2c,0xb9,0x62,0xac,0x59,0x07,0x5b,0x96,0x4b,0x07,0x15,0x2d,0x23,0x4b,0x70], "MD5 calculation failed");
         } else {
             XCTAssert(false, "Missing result")
         }
@@ -30,7 +30,7 @@ final class CryptoSwiftTests: XCTestCase {
         let string:NSString = ""
         let data:NSData = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
         if let hashData = Hash.md5(data).calculate() {
-            XCTAssertEqual(hashData.toHexString(), "d41d8cd98f00b204e9800998ecf8427e", "MD5 calculation failed")
+            XCTAssertEqual(hashData, [0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e], "MD5 calculation failed")
         } else {
             XCTAssert(false, "Missing result")
         }
@@ -196,15 +196,9 @@ final class CryptoSwiftTests: XCTestCase {
         }
     }
     
-    func testCRC32Async() {
-        let expect = expectationWithDescription("CRC32")
-        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
-            self.testCRC32()
-            expect.fulfill()
-        })
-
-        waitForExpectationsWithTimeout(10, handler: { (error) -> Void in
-            XCTAssertNil(error, "CRC32 async failed")
-        })
+    func testChecksum() {
+        let data:NSData = NSData(bytes: [49, 50, 51] as [UInt8], length: 3)
+        XCTAssert(data.checksum() == 0x96, "Invalid checksum")
     }
+
 }