diff --git a/Cache.podspec b/Cache.podspec index 4e262ec..b93ddf0 100644 --- a/Cache.podspec +++ b/Cache.podspec @@ -19,7 +19,6 @@ Pod::Spec.new do |s| s.tvos.source_files = 'Source/{iOS,Shared}/**/*' s.frameworks = 'Foundation' - s.dependency 'SwiftHash', '~> 2.0.0' s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.0' } end diff --git a/Cache.xcodeproj/project.pbxproj b/Cache.xcodeproj/project.pbxproj index 39e6d9f..e9920b3 100644 --- a/Cache.xcodeproj/project.pbxproj +++ b/Cache.xcodeproj/project.pbxproj @@ -100,6 +100,10 @@ D2CF98851F69598900CE8F68 /* TypeWrapperStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2CF98841F69598900CE8F68 /* TypeWrapperStorage.swift */; }; D2CF98871F695B8F00CE8F68 /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2CF98861F695B8F00CE8F68 /* Types.swift */; }; D2CF98891F695F9400CE8F68 /* TypeWrapperStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2CF98881F695F9400CE8F68 /* TypeWrapperStorageTests.swift */; }; + D2D4CC161FA3145000E4A2D5 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D4CC151FA3145000E4A2D5 /* MD5.swift */; }; + D2D4CC171FA3145000E4A2D5 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D4CC151FA3145000E4A2D5 /* MD5.swift */; }; + D2D4CC181FA3145000E4A2D5 /* MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D4CC151FA3145000E4A2D5 /* MD5.swift */; }; + D2D4CC1A1FA3166900E4A2D5 /* MD5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D4CC191FA3166900E4A2D5 /* MD5Tests.swift */; }; D5291D1D1C2837DB00B702C9 /* Cache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5DC59E01C20593E003BD79B /* Cache.framework */; }; D5291D6A1C283B5400B702C9 /* Cache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5291D601C283B5300B702C9 /* Cache.framework */; }; D5291D851C283C7C00B702C9 /* TestHelper+OSX.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291D811C283C7000B702C9 /* TestHelper+OSX.swift */; }; @@ -173,6 +177,8 @@ D2CF98841F69598900CE8F68 /* TypeWrapperStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeWrapperStorage.swift; sourceTree = ""; }; D2CF98861F695B8F00CE8F68 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = ""; }; D2CF98881F695F9400CE8F68 /* TypeWrapperStorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeWrapperStorageTests.swift; sourceTree = ""; }; + D2D4CC151FA3145000E4A2D5 /* MD5.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MD5.swift; sourceTree = ""; }; + D2D4CC191FA3166900E4A2D5 /* MD5Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MD5Tests.swift; sourceTree = ""; }; D5291CDF1C28374800B702C9 /* TestHelper+iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TestHelper+iOS.swift"; sourceTree = ""; }; D5291D181C2837DB00B702C9 /* Cache-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Cache-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; D5291D231C28380100B702C9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -288,6 +294,7 @@ D2CF98591F694FFA00CE8F68 /* StorageError.swift */, D2CF98861F695B8F00CE8F68 /* Types.swift */, D292DAFC1F6A970B0060F614 /* Result.swift */, + D2D4CC151FA3145000E4A2D5 /* MD5.swift */, ); path = Library; sourceTree = ""; @@ -334,6 +341,7 @@ D2CF98761F69513800CE8F68 /* ImageWrapperTests.swift */, D2CF98771F69513800CE8F68 /* TypeWrapperTests.swift */, D285143E1F6FFE1F00C674D1 /* ObjectConverterTests.swift */, + D2D4CC191FA3166900E4A2D5 /* MD5Tests.swift */, ); path = Library; sourceTree = ""; @@ -510,7 +518,6 @@ BDEDD3741DBCEB8A007416A6 /* Sources */, BDEDD3751DBCEB8A007416A6 /* Frameworks */, BDEDD3761DBCEB8A007416A6 /* Resources */, - BDEDD3971DBCEE2D007416A6 /* ShellScript */, ); buildRules = ( ); @@ -529,7 +536,6 @@ D5291D141C2837DB00B702C9 /* Sources */, D5291D151C2837DB00B702C9 /* Frameworks */, D5291D161C2837DB00B702C9 /* Resources */, - D5291D591C283AA700B702C9 /* ShellScript */, ); buildRules = ( ); @@ -567,7 +573,6 @@ D5291D651C283B5400B702C9 /* Sources */, D5291D661C283B5400B702C9 /* Frameworks */, D5291D671C283B5400B702C9 /* Resources */, - D5291D9F1C283ECD00B702C9 /* ShellScript */, ); buildRules = ( ); @@ -588,7 +593,6 @@ D5DC59DD1C20593E003BD79B /* Headers */, D5DC59DE1C20593E003BD79B /* Resources */, BD58C3AD1CF2E9FD003F7141 /* SwiftLint */, - D2AB91761F83936E008610B5 /* Carthage */, ); buildRules = ( ); @@ -743,63 +747,6 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; }; - BDEDD3971DBCEE2D007416A6 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/Carthage/Build/tvOS/SwiftHash.framework", - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks"; - }; - D2AB91761F83936E008610B5 /* Carthage */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/Carthage/Build/iOS/SwiftHash.framework", - ); - name = Carthage; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks"; - }; - D5291D591C283AA700B702C9 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/Carthage/Build/iOS/SwiftHash.framework", - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks"; - }; - D5291D9F1C283ECD00B702C9 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/Carthage/Build/Mac/SwiftHash.framework", - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -814,6 +761,7 @@ D21B66871F6A723C00125DE1 /* ExpirationMode.swift in Sources */, D21B66881F6A723C00125DE1 /* Expiry.swift in Sources */, D21B669E1F6A724700125DE1 /* MemoryConfig.swift in Sources */, + D2D4CC181FA3145000E4A2D5 /* MD5.swift in Sources */, D21B66951F6A724000125DE1 /* MemoryStorage.swift in Sources */, D292DAF31F6A85F30060F614 /* SyncStorage.swift in Sources */, D21B668C1F6A723C00125DE1 /* Types.swift in Sources */, @@ -856,6 +804,7 @@ D28C9BAC1F67ECD400C180C1 /* TestHelper+iOS.swift in Sources */, D2CF98211F69427C00CE8F68 /* TestHelper.swift in Sources */, D2CF987F1F69513800CE8F68 /* ImageWrapperTests.swift in Sources */, + D2D4CC1A1FA3166900E4A2D5 /* MD5Tests.swift in Sources */, D292DB041F6AA0730060F614 /* AsyncStorageTests.swift in Sources */, D28C9BAF1F67EF8300C180C1 /* UIImage+ExtensionsTests.swift in Sources */, D2CF987D1F69513800CE8F68 /* MemoryCapsuleTests.swift in Sources */, @@ -879,6 +828,7 @@ D21B667E1F6A723C00125DE1 /* ExpirationMode.swift in Sources */, D21B667F1F6A723C00125DE1 /* Expiry.swift in Sources */, D21B669C1F6A724600125DE1 /* MemoryConfig.swift in Sources */, + D2D4CC171FA3145000E4A2D5 /* MD5.swift in Sources */, D21B668F1F6A723F00125DE1 /* MemoryStorage.swift in Sources */, D292DAF21F6A85F30060F614 /* SyncStorage.swift in Sources */, D21B66831F6A723C00125DE1 /* Types.swift in Sources */, @@ -924,6 +874,7 @@ D2CF98621F694FFA00CE8F68 /* Date+Extensions.swift in Sources */, D2CF98641F694FFA00CE8F68 /* DataSerializer.swift in Sources */, D2CF986B1F694FFA00CE8F68 /* DiskStorage.swift in Sources */, + D2D4CC161FA3145000E4A2D5 /* MD5.swift in Sources */, D292DAF11F6A85F30060F614 /* SyncStorage.swift in Sources */, D2CF98601F694FFA00CE8F68 /* DiskConfig.swift in Sources */, D292DAFD1F6A970B0060F614 /* Result.swift in Sources */, @@ -975,10 +926,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/tvOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1004,10 +952,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/tvOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1028,10 +973,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; DEVELOPMENT_TEAM = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Tests/tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Cache-tvOS-Tests"; @@ -1052,10 +994,7 @@ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; DEVELOPMENT_TEAM = ""; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Tests/tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Cache-tvOS-Tests"; @@ -1070,10 +1009,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Tests/iOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Cache-iOS-Tests"; @@ -1087,10 +1023,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Tests/iOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Cache-iOS-Tests"; @@ -1108,10 +1041,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_VERSION = A; INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/Mac/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1133,10 +1063,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_VERSION = A; INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/Mac/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1154,10 +1081,7 @@ buildSettings = { CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Tests/Mac/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11; @@ -1172,10 +1096,7 @@ buildSettings = { CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/Tests/Mac/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.11; @@ -1301,10 +1222,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -1323,10 +1241,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; diff --git a/Cartfile b/Cartfile deleted file mode 100644 index 95db657..0000000 --- a/Cartfile +++ /dev/null @@ -1 +0,0 @@ -github "onmyway133/SwiftHash" == 2.0.1 diff --git a/Cartfile.resolved b/Cartfile.resolved deleted file mode 100644 index e7e5c91..0000000 --- a/Cartfile.resolved +++ /dev/null @@ -1 +0,0 @@ -github "onmyway133/SwiftHash" "2.0.1" diff --git a/Source/Shared/Library/MD5.swift b/Source/Shared/Library/MD5.swift new file mode 100644 index 0000000..8a97e2b --- /dev/null +++ b/Source/Shared/Library/MD5.swift @@ -0,0 +1,281 @@ +// swiftlint:disable comma function_parameter_count variable_name syntactic_sugar function_body_length vertical_whitespace + +// https://github.com/onmyway133/SwiftHash/blob/master/Sources/MD5.swift + +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/** + * SwiftHash + * Copyright (c) Khoa Pham 2017 + * Licensed under the MIT license. See LICENSE file. + */ + +import Foundation + +// MARK: - Public + +func MD5(_ input: String) -> String { + return hex_md5(input) +} + +// MARK: - Functions + +func hex_md5(_ input: String) -> String { + return rstr2hex(rstr_md5(str2rstr_utf8(input))) +} + +func str2rstr_utf8(_ input: String) -> [CUnsignedChar] { + return Array(input.utf8) +} + +func rstr2tr(_ input: [CUnsignedChar]) -> String { + var output: String = "" + + input.forEach { + output.append(String(UnicodeScalar($0))) + } + + return output +} + +/* + * Convert a raw string to a hex string + */ +func rstr2hex(_ input: [CUnsignedChar]) -> String { + let hexTab: [Character] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"] + var output: [Character] = [] + + for i in 0..> 4) & 0x0F)] + let value2 = hexTab[Int(Int32(x) & 0x0F)] + + output.append(value1) + output.append(value2) + } + + return String(output) +} + +/* + * Convert a raw string to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ +func rstr2binl(_ input: [CUnsignedChar]) -> [Int32] { + var output: [Int: Int32] = [:] + + for i in stride(from: 0, to: input.count * 8, by: 8) { + let value: Int32 = (Int32(input[i/8]) & 0xFF) << (Int32(i) % 32) + + output[i >> 5] = unwrap(output[i >> 5]) | value + } + + return dictionary2array(output) +} + +/* + * Convert an array of little-endian words to a string + */ +func binl2rstr(_ input: [Int32]) -> [CUnsignedChar] { + var output: [CUnsignedChar] = [] + + for i in stride(from: 0, to: input.count * 32, by: 8) { + // [i>>5] >>> + let value: Int32 = zeroFillRightShift(input[i>>5], Int32(i % 32)) & 0xFF + output.append(CUnsignedChar(value)) + } + + return output +} + +/* + * Calculate the MD5 of a raw string + */ +func rstr_md5(_ input: [CUnsignedChar]) -> [CUnsignedChar] { + return binl2rstr(binl_md5(rstr2binl(input), input.count * 8)) +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +func safe_add(_ x: Int32, _ y: Int32) -> Int32 { + let lsw = (x & 0xFFFF) + (y & 0xFFFF) + let msw = (x >> 16) + (y >> 16) + (lsw >> 16) + return (msw << 16) | (lsw & 0xFFFF) +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +func bit_rol(_ num: Int32, _ cnt: Int32) -> Int32 { + // num >>> + return (num << cnt) | zeroFillRightShift(num, (32 - cnt)) +} + + +/* + * These funcs implement the four basic operations the algorithm uses. + */ +func md5_cmn(_ q: Int32, _ a: Int32, _ b: Int32, _ x: Int32, _ s: Int32, _ t: Int32) -> Int32 { + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b) +} + +func md5_ff(_ a: Int32, _ b: Int32, _ c: Int32, _ d: Int32, _ x: Int32, _ s: Int32, _ t: Int32) -> Int32 { + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t) +} + +func md5_gg(_ a: Int32, _ b: Int32, _ c: Int32, _ d: Int32, _ x: Int32, _ s: Int32, _ t: Int32) -> Int32 { + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t) +} + +func md5_hh(_ a: Int32, _ b: Int32, _ c: Int32, _ d: Int32, _ x: Int32, _ s: Int32, _ t: Int32) -> Int32 { + return md5_cmn(b ^ c ^ d, a, b, x, s, t) +} + +func md5_ii(_ a: Int32, _ b: Int32, _ c: Int32, _ d: Int32, _ x: Int32, _ s: Int32, _ t: Int32) -> Int32 { + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t) +} + + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ +func binl_md5(_ input: [Int32], _ len: Int) -> [Int32] { + /* append padding */ + + var x: [Int: Int32] = [:] + for (index, value) in input.enumerated() { + x[index] = value + } + + let value: Int32 = 0x80 << Int32((len) % 32) + x[len >> 5] = unwrap(x[len >> 5]) | value + + // >>> 9 + let index = (((len + 64) >> 9) << 4) + 14 + x[index] = unwrap(x[index]) | Int32(len) + + var a: Int32 = 1732584193 + var b: Int32 = -271733879 + var c: Int32 = -1732584194 + var d: Int32 = 271733878 + + for i in stride(from: 0, to: length(x), by: 16) { + let olda: Int32 = a + let oldb: Int32 = b + let oldc: Int32 = c + let oldd: Int32 = d + + a = md5_ff(a, b, c, d, unwrap(x[i + 0]), 7 , -680876936) + d = md5_ff(d, a, b, c, unwrap(x[i + 1]), 12, -389564586) + c = md5_ff(c, d, a, b, unwrap(x[i + 2]), 17, 606105819) + b = md5_ff(b, c, d, a, unwrap(x[i + 3]), 22, -1044525330) + a = md5_ff(a, b, c, d, unwrap(x[i + 4]), 7 , -176418897) + d = md5_ff(d, a, b, c, unwrap(x[i + 5]), 12, 1200080426) + c = md5_ff(c, d, a, b, unwrap(x[i + 6]), 17, -1473231341) + b = md5_ff(b, c, d, a, unwrap(x[i + 7]), 22, -45705983) + a = md5_ff(a, b, c, d, unwrap(x[i + 8]), 7 , 1770035416) + d = md5_ff(d, a, b, c, unwrap(x[i + 9]), 12, -1958414417) + c = md5_ff(c, d, a, b, unwrap(x[i + 10]), 17, -42063) + b = md5_ff(b, c, d, a, unwrap(x[i + 11]), 22, -1990404162) + a = md5_ff(a, b, c, d, unwrap(x[i + 12]), 7 , 1804603682) + d = md5_ff(d, a, b, c, unwrap(x[i + 13]), 12, -40341101) + c = md5_ff(c, d, a, b, unwrap(x[i + 14]), 17, -1502002290) + b = md5_ff(b, c, d, a, unwrap(x[i + 15]), 22, 1236535329) + + a = md5_gg(a, b, c, d, unwrap(x[i + 1]), 5 , -165796510) + d = md5_gg(d, a, b, c, unwrap(x[i + 6]), 9 , -1069501632) + c = md5_gg(c, d, a, b, unwrap(x[i + 11]), 14, 643717713) + b = md5_gg(b, c, d, a, unwrap(x[i + 0]), 20, -373897302) + a = md5_gg(a, b, c, d, unwrap(x[i + 5]), 5 , -701558691) + d = md5_gg(d, a, b, c, unwrap(x[i + 10]), 9 , 38016083) + c = md5_gg(c, d, a, b, unwrap(x[i + 15]), 14, -660478335) + b = md5_gg(b, c, d, a, unwrap(x[i + 4]), 20, -405537848) + a = md5_gg(a, b, c, d, unwrap(x[i + 9]), 5 , 568446438) + d = md5_gg(d, a, b, c, unwrap(x[i + 14]), 9 , -1019803690) + c = md5_gg(c, d, a, b, unwrap(x[i + 3]), 14, -187363961) + b = md5_gg(b, c, d, a, unwrap(x[i + 8]), 20, 1163531501) + a = md5_gg(a, b, c, d, unwrap(x[i + 13]), 5 , -1444681467) + d = md5_gg(d, a, b, c, unwrap(x[i + 2]), 9 , -51403784) + c = md5_gg(c, d, a, b, unwrap(x[i + 7]), 14, 1735328473) + b = md5_gg(b, c, d, a, unwrap(x[i + 12]), 20, -1926607734) + + a = md5_hh(a, b, c, d, unwrap(x[i + 5]), 4 , -378558) + d = md5_hh(d, a, b, c, unwrap(x[i + 8]), 11, -2022574463) + c = md5_hh(c, d, a, b, unwrap(x[i + 11]), 16, 1839030562) + b = md5_hh(b, c, d, a, unwrap(x[i + 14]), 23, -35309556) + a = md5_hh(a, b, c, d, unwrap(x[i + 1]), 4 , -1530992060) + d = md5_hh(d, a, b, c, unwrap(x[i + 4]), 11, 1272893353) + c = md5_hh(c, d, a, b, unwrap(x[i + 7]), 16, -155497632) + b = md5_hh(b, c, d, a, unwrap(x[i + 10]), 23, -1094730640) + a = md5_hh(a, b, c, d, unwrap(x[i + 13]), 4 , 681279174) + d = md5_hh(d, a, b, c, unwrap(x[i + 0]), 11, -358537222) + c = md5_hh(c, d, a, b, unwrap(x[i + 3]), 16, -722521979) + b = md5_hh(b, c, d, a, unwrap(x[i + 6]), 23, 76029189) + a = md5_hh(a, b, c, d, unwrap(x[i + 9]), 4 , -640364487) + d = md5_hh(d, a, b, c, unwrap(x[i + 12]), 11, -421815835) + c = md5_hh(c, d, a, b, unwrap(x[i + 15]), 16, 530742520) + b = md5_hh(b, c, d, a, unwrap(x[i + 2]), 23, -995338651) + + a = md5_ii(a, b, c, d, unwrap(x[i + 0]), 6 , -198630844) + d = md5_ii(d, a, b, c, unwrap(x[i + 7]), 10, 1126891415) + c = md5_ii(c, d, a, b, unwrap(x[i + 14]), 15, -1416354905) + b = md5_ii(b, c, d, a, unwrap(x[i + 5]), 21, -57434055) + a = md5_ii(a, b, c, d, unwrap(x[i + 12]), 6 , 1700485571) + d = md5_ii(d, a, b, c, unwrap(x[i + 3]), 10, -1894986606) + c = md5_ii(c, d, a, b, unwrap(x[i + 10]), 15, -1051523) + b = md5_ii(b, c, d, a, unwrap(x[i + 1]), 21, -2054922799) + a = md5_ii(a, b, c, d, unwrap(x[i + 8]), 6 , 1873313359) + d = md5_ii(d, a, b, c, unwrap(x[i + 15]), 10, -30611744) + c = md5_ii(c, d, a, b, unwrap(x[i + 6]), 15, -1560198380) + b = md5_ii(b, c, d, a, unwrap(x[i + 13]), 21, 1309151649) + a = md5_ii(a, b, c, d, unwrap(x[i + 4]), 6 , -145523070) + d = md5_ii(d, a, b, c, unwrap(x[i + 11]), 10, -1120210379) + c = md5_ii(c, d, a, b, unwrap(x[i + 2]), 15, 718787259) + b = md5_ii(b, c, d, a, unwrap(x[i + 9]), 21, -343485551) + + a = safe_add(a, olda) + b = safe_add(b, oldb) + c = safe_add(c, oldc) + d = safe_add(d, oldd) + } + + return [a, b, c, d] +} + +// MARK: - Helper + +func length(_ dictionary: [Int: Int32]) -> Int { + return (dictionary.keys.max() ?? 0) + 1 +} + +func dictionary2array(_ dictionary: [Int: Int32]) -> [Int32] { + var array = Array(repeating: 0, count: dictionary.keys.count) + + for i in Array(dictionary.keys).sorted() { + array[i] = unwrap(dictionary[i]) + } + + return array +} + +func unwrap(_ value: Int32?, _ fallback: Int32 = 0) -> Int32 { + if let value = value { + return value + } + + return fallback +} + +func zeroFillRightShift(_ num: Int32, _ count: Int32) -> Int32 { + let value = UInt32(bitPattern: num) >> UInt32(bitPattern: count) + return Int32(bitPattern: value) +} diff --git a/Source/Shared/Storage/DiskStorage.swift b/Source/Shared/Storage/DiskStorage.swift index 7d26311..16e316a 100644 --- a/Source/Shared/Storage/DiskStorage.swift +++ b/Source/Shared/Storage/DiskStorage.swift @@ -1,5 +1,4 @@ import Foundation -import SwiftHash /// Save objects to file on disk final class DiskStorage { diff --git a/Tests/iOS/Tests/Library/MD5Tests.swift b/Tests/iOS/Tests/Library/MD5Tests.swift new file mode 100644 index 0000000..34b4f54 --- /dev/null +++ b/Tests/iOS/Tests/Library/MD5Tests.swift @@ -0,0 +1,84 @@ +// https://github.com/onmyway133/SwiftHash/blob/master/SwiftHashTests/Tests.swift + +import XCTest +@testable import Cache + +class Tests: XCTestCase { + + func testHelper() { + XCTAssertEqual(str2rstr_utf8("hello"), [104, 101, 108, 108, 111]) + + let hello = str2rstr_utf8("hello") + let world = str2rstr_utf8("world") + let google = str2rstr_utf8("https://www.google.com") + + XCTAssertEqual(rstr2tr(hello), "hello") + XCTAssertEqual(rstr2tr(world), "world") + XCTAssertEqual(rstr2tr(google), "https://www.google.com") + + XCTAssertEqual(rstr2binl(hello), [1819043176, 111]) + XCTAssertEqual(rstr2binl(world), [1819438967, 100]) + XCTAssertEqual(rstr2binl(google), [1886680168, 791624307, 779581303, 1735356263, 1663985004, 28015]) + + XCTAssertEqual(rstr2hex(hello), "68656C6C6F") + XCTAssertEqual(rstr2hex(world), "776F726C64") + XCTAssertEqual(rstr2hex(google), "68747470733A2F2F7777772E676F6F676C652E636F6D") + + XCTAssertEqual(Int32(-991732713) << Int32(12), 901869568) + XCTAssertEqual(Int32(991732713) << Int32(12), -901869568) + XCTAssertEqual(zeroFillRightShift(-991732713, (32 - 12)), 3150) + + XCTAssertEqual(bit_rol(1589092186, 17), 1052032367) + XCTAssertEqual(bit_rol(-991732713, 12), 901872718) + + XCTAssertEqual(md5_cmn(-617265063, -615378706, -617265106, 0, 17, -1473231341), 434767261) + + XCTAssertEqual(md5_ff(271733878, -615343318, -271733879, -1732584194, 32879, 12, -389564586), 286529400) + + XCTAssertEqual(binl_md5(rstr2binl(hello), hello.count * 8), [708854109, 1982483388, -1851952711, -1832577264]) + XCTAssertEqual(binl_md5(rstr2binl(world), world.count * 8), [925923709, -2046724448, -2113778857, -415894286]) + } + + func testMD5() { + XCTAssertEqual(MD5("hello"), + "5D41402ABC4B2A76B9719D911017C592") + XCTAssertEqual(MD5("world"), + "7D793037A0760186574B0282F2F435E7") + XCTAssertEqual(MD5("https://www.google.com"), + "8FFDEFBDEC956B595D257F0AAEEFD623") + XCTAssertEqual(MD5("https://www.google.com/logos/doodles/2016/parents-day-in-korea-5757703554072576-hp2x.jpg"), + "0DFB10E8D2AE771B3B3ED4544139644E") + XCTAssertEqual(MD5("https://unsplash.it/600/300/?image=1"), + "D59E956EBB1BE415970F04EC77F4C875") + XCTAssertEqual(MD5(""), + "D41D8CD98F00B204E9800998ECF8427E") + XCTAssertEqual(MD5("ABCDEFGHIJKLMNOPQRSTWXYZ1234567890"), + "B8F4F38629EC4F4A23F5DCC6086F8035") + XCTAssertEqual(MD5("abcdefghijklmnopqrstwxyz1234567890"), + "B2E875F4D53CCF6CEFB5CDA3F86FC542") + XCTAssertEqual(MD5("0123456789"), + "781E5E245D69B566979B86E28D23F2C7") + XCTAssertEqual(MD5("0"), + "CFCD208495D565EF66E7DFF9F98764DA") + XCTAssertEqual(MD5("https://twitter.com/_HairForceOne/status/745235759460810752"), + "40C2BFA3D7BFC7A453013ECD54022255") + XCTAssertEqual(MD5("Det er et velkjent faktum at lesere distraheres av lesbart innhold på en side når man ser på dens layout. Poenget med å bruke Lorem Ipsum er at det har en mer eller mindre normal fordeling av bokstaver i ord, i motsetning til 'Innhold her, innhold her', og gir inntrykk av å være lesbar tekst. Mange webside- og sideombrekkingsprogrammer bruker nå Lorem Ipsum som sin standard for provisorisk tekst"), + "6B2880BCC7554CF07E72DB9C99BF3284") + XCTAssertEqual(MD5("\\"), + "28D397E87306B8631F3ED80D858D35F0") + XCTAssertEqual(MD5("http://res.cloudinary.com/demo/image/upload/w_300,h_200,c_crop/sample.jpg"), + "6E30D9CC4C08BE4EEA49076328D4C1F0") + XCTAssertEqual(MD5("http://res.cloudinary.com/demo/image/upload/x_355,y_410,w_300,h_200,c_crop/brown_sheep.jpg"), + "019E9D72B5AF84EF114868875C1597ED") + XCTAssertEqual(MD5("http://www.w3schools.com/tags/html_form_submit.asp?text=Hello+G%C3%BCnter"), + "C89A2146CD3DF34ECDA86B6E0709B3FD") + XCTAssertEqual(MD5("!%40%23%24%25%5E%26*()%2C.%3C%3E%5C'1234567890-%3D"), + "09A1790760693160E74B9D6FCEC7EF64") + } + + func testMD5_Data() { + let data = "https://www.google.com".data(using: String.Encoding.utf8) + XCTAssertEqual(MD5(String(data: data!, encoding: String.Encoding.utf8)!), + "8FFDEFBDEC956B595D257F0AAEEFD623") + } +} diff --git a/Tests/iOS/Tests/Storage/DiskStorageTests.swift b/Tests/iOS/Tests/Storage/DiskStorageTests.swift index 5186819..5379d7d 100644 --- a/Tests/iOS/Tests/Storage/DiskStorageTests.swift +++ b/Tests/iOS/Tests/Storage/DiskStorageTests.swift @@ -1,5 +1,4 @@ import XCTest -import SwiftHash @testable import Cache final class DiskStorageTests: XCTestCase { diff --git a/Tests/iOS/Tests/Storage/HybridStorageTests.swift b/Tests/iOS/Tests/Storage/HybridStorageTests.swift index f38ffca..a93e4b5 100644 --- a/Tests/iOS/Tests/Storage/HybridStorageTests.swift +++ b/Tests/iOS/Tests/Storage/HybridStorageTests.swift @@ -1,5 +1,4 @@ import XCTest -import SwiftHash @testable import Cache final class HybridStorageTests: XCTestCase {