diff --git a/.gitignore b/.gitignore index 93c86d3..9a73f4b 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,4 @@ Carthage/Build # Note: if you ignore the Pods directory, make sure to uncomment # `pod install` in .travis.yml # -# Pods/ +Pods/ diff --git a/.travis.yml b/.travis.yml index add7bec..5e624d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,10 @@ -# references: -# * https://www.objc.io/issues/6-build-tools/travis-ci/ -# * https://github.com/supermarin/xcpretty#usage - -osx_image: xcode7.3 language: objective-c -# cache: cocoapods -# podfile: Example/Podfile -# before_install: -# - gem install cocoapods # Since Travis is not always on latest version -# - pod install --project-directory=Example +osx_image: xcode10 + +before_install: +- gem update fastlane --no-ri --no-rdoc --no-document +- gem update cocoapods --no-ri --no-rdoc --no-document + script: -- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/Hasher.xcworkspace -scheme Hasher-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty -- pod lib lint +- cd Example/ +- fastlane ci \ No newline at end of file diff --git a/Example/Hasher.xcodeproj/project.pbxproj b/Example/Hasher.xcodeproj/project.pbxproj index e83d087..f6769f0 100644 --- a/Example/Hasher.xcodeproj/project.pbxproj +++ b/Example/Hasher.xcodeproj/project.pbxproj @@ -7,13 +7,16 @@ objects = { /* Begin PBXBuildFile section */ + 2F890663223659D10024AD4A /* SHA256Spec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F890661223659630024AD4A /* SHA256Spec.swift */; }; 39039F6CA96FAB96D47065B0 /* Pods_Hasher_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED0AC42A822D4DAD5CC11588 /* Pods_Hasher_Example.framework */; }; 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; - 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 97B30160224FFB9B00B5522B /* MD5Spec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97B3015F224FFB9B00B5522B /* MD5Spec.swift */; }; + 97B30162224FFBD900B5522B /* SHA1Spec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97B30161224FFBD900B5522B /* SHA1Spec.swift */; }; + 97B30164224FFC4A00B5522B /* SHA512Spec copy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97B30163224FFC4A00B5522B /* SHA512Spec copy.swift */; }; FCDE3CBD59830EDD2BCB27AB /* Pods_Hasher_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 714A7983E7E375481E74239F /* Pods_Hasher_Tests.framework */; }; /* End PBXBuildFile section */ @@ -29,7 +32,8 @@ /* Begin PBXFileReference section */ 23F8B92FE40C46CBE0BA0DD2 /* Pods-Hasher_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Hasher_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Hasher_Tests/Pods-Hasher_Tests.release.xcconfig"; sourceTree = ""; }; - 316F91765520CFF6FA8E1543 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = ../README.md; sourceTree = ""; }; + 2F890661223659630024AD4A /* SHA256Spec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SHA256Spec.swift; sourceTree = ""; }; + 316F91765520CFF6FA8E1543 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 3BB972BEA00B2C0B1E2D1841 /* Pods-Hasher_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Hasher_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Hasher_Example/Pods-Hasher_Example.release.xcconfig"; sourceTree = ""; }; 4352E75DBCC5B1B487962BC9 /* Pods-Hasher_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Hasher_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Hasher_Example/Pods-Hasher_Example.debug.xcconfig"; sourceTree = ""; }; 607FACD01AFB9204008FA782 /* Hasher_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Hasher_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -41,11 +45,13 @@ 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 607FACE51AFB9204008FA782 /* Hasher_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hasher_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 714A7983E7E375481E74239F /* Pods_Hasher_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Hasher_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 87262ABBCD174A07EAAC0471 /* Pods-Hasher_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Hasher_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Hasher_Tests/Pods-Hasher_Tests.debug.xcconfig"; sourceTree = ""; }; - BDFF5DDC0292BB75AAC5E3D4 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; - C1A479615A37D0B75640D439 /* Hasher.podspec */ = {isa = PBXFileReference; includeInIndex = 1; name = Hasher.podspec; path = ../Hasher.podspec; sourceTree = ""; }; + 97B3015F224FFB9B00B5522B /* MD5Spec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MD5Spec.swift; sourceTree = ""; }; + 97B30161224FFBD900B5522B /* SHA1Spec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SHA1Spec.swift; sourceTree = ""; }; + 97B30163224FFC4A00B5522B /* SHA512Spec copy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SHA512Spec copy.swift"; sourceTree = ""; }; + BDFF5DDC0292BB75AAC5E3D4 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + C1A479615A37D0B75640D439 /* Hasher.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Hasher.podspec; path = ../Hasher.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; ED0AC42A822D4DAD5CC11588 /* Pods_Hasher_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Hasher_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -126,7 +132,10 @@ 607FACE81AFB9204008FA782 /* Tests */ = { isa = PBXGroup; children = ( - 607FACEB1AFB9204008FA782 /* Tests.swift */, + 97B3015F224FFB9B00B5522B /* MD5Spec.swift */, + 97B30161224FFBD900B5522B /* SHA1Spec.swift */, + 2F890661223659630024AD4A /* SHA256Spec.swift */, + 97B30163224FFC4A00B5522B /* SHA512Spec copy.swift */, 607FACE91AFB9204008FA782 /* Supporting Files */, ); path = Tests; @@ -189,7 +198,7 @@ 607FACE11AFB9204008FA782 /* Sources */, 607FACE21AFB9204008FA782 /* Frameworks */, 607FACE31AFB9204008FA782 /* Resources */, - B007DF8B6A5A53A0C70C745F /* [CP] Embed Pods Frameworks */, + DBC2F2FA4BB4E7E9F1BB1542 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -213,10 +222,12 @@ TargetAttributes = { 607FACCF1AFB9204008FA782 = { CreatedOnToolsVersion = 6.3.1; + DevelopmentTeam = 6RS7DS4QV5; LastSwiftMigration = 0900; }; 607FACE41AFB9204008FA782 = { CreatedOnToolsVersion = 6.3.1; + DevelopmentTeam = 6RS7DS4QV5; LastSwiftMigration = 0900; TestTargetID = 607FACCF1AFB9204008FA782; }; @@ -227,6 +238,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -284,7 +296,7 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - B007DF8B6A5A53A0C70C745F /* [CP] Embed Pods Frameworks */ = { + BD1ED8966627D877216A12B8 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -292,23 +304,21 @@ inputFileListPaths = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Hasher_Tests/Pods-Hasher_Tests-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework", - "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", + "${PODS_ROOT}/Target Support Files/Pods-Hasher_Example/Pods-Hasher_Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Hasher/Hasher.framework", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( ); outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Hasher.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Hasher_Tests/Pods-Hasher_Tests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Hasher_Example/Pods-Hasher_Example-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - BD1ED8966627D877216A12B8 /* [CP] Embed Pods Frameworks */ = { + BF72F3C5A1F8046238504DDB /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -316,21 +326,21 @@ inputFileListPaths = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Hasher_Example/Pods-Hasher_Example-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Hasher/Hasher.framework", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Hasher.framework", + "$(DERIVED_FILE_DIR)/Pods-Hasher_Tests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Hasher_Example/Pods-Hasher_Example-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - BF72F3C5A1F8046238504DDB /* [CP] Check Pods Manifest.lock */ = { + DBC2F2FA4BB4E7E9F1BB1542 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -338,18 +348,20 @@ inputFileListPaths = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", + "${PODS_ROOT}/Target Support Files/Pods-Hasher_Tests/Pods-Hasher_Tests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework", + "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Hasher_Tests-checkManifestLockResult.txt", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Hasher_Tests/Pods-Hasher_Tests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -368,7 +380,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + 97B30160224FFB9B00B5522B /* MD5Spec.swift in Sources */, + 97B30162224FFBD900B5522B /* SHA1Spec.swift in Sources */, + 2F890663223659D10024AD4A /* SHA256Spec.swift in Sources */, + 97B30164224FFC4A00B5522B /* SHA512Spec copy.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -447,7 +462,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -493,7 +508,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -506,7 +521,9 @@ baseConfigurationReference = 4352E75DBCC5B1B487962BC9 /* Pods-Hasher_Example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 6RS7DS4QV5; INFOPLIST_FILE = Hasher/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; @@ -521,7 +538,9 @@ baseConfigurationReference = 3BB972BEA00B2C0B1E2D1841 /* Pods-Hasher_Example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 6RS7DS4QV5; INFOPLIST_FILE = Hasher/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; @@ -535,6 +554,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 87262ABBCD174A07EAAC0471 /* Pods-Hasher_Tests.debug.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 6RS7DS4QV5; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", @@ -557,6 +577,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 23F8B92FE40C46CBE0BA0DD2 /* Pods-Hasher_Tests.release.xcconfig */; buildSettings = { + DEVELOPMENT_TEAM = 6RS7DS4QV5; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", diff --git a/Example/Hasher.xcodeproj/xcshareddata/xcschemes/Hasher-Example.xcscheme b/Example/Hasher.xcodeproj/xcshareddata/xcschemes/Hasher-Example.xcscheme index 825b925..a8c9dac 100644 --- a/Example/Hasher.xcodeproj/xcshareddata/xcschemes/Hasher-Example.xcscheme +++ b/Example/Hasher.xcodeproj/xcshareddata/xcschemes/Hasher-Example.xcscheme @@ -40,8 +40,18 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" + codeCoverageEnabled = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -70,7 +80,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Example/Hasher.xcworkspace/contents.xcworkspacedata b/Example/Hasher.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ca74f8e --- /dev/null +++ b/Example/Hasher.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Example/Hasher.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/Hasher.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Example/Hasher.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Example/Hasher.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Example/Hasher.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/Example/Hasher.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/Example/Hasher/Base.lproj/Main.storyboard b/Example/Hasher/Base.lproj/Main.storyboard index 4727d65..fbc8859 100644 --- a/Example/Hasher/Base.lproj/Main.storyboard +++ b/Example/Hasher/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -20,8 +20,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Hasher/ViewController.swift b/Example/Hasher/ViewController.swift index 6e625b0..43d071f 100644 --- a/Example/Hasher/ViewController.swift +++ b/Example/Hasher/ViewController.swift @@ -7,18 +7,97 @@ // import UIKit +import Hasher class ViewController: UIViewController { + @IBOutlet weak var outputTypeSelector: UISegmentedControl! + @IBOutlet weak var hashTypeSelector: UISegmentedControl! + @IBOutlet weak var textField: UITextField! + @IBOutlet weak var resultLabel: UILabel! + + let availableHashes = ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"] + let availableOutputs = ["hex", "base64"] + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. + self.setupSelector() + } + + private func setupSelector() { + self.hashTypeSelector.removeAllSegments() + self.availableHashes.enumerated().forEach { (index, hash) in + self.hashTypeSelector.insertSegment(withTitle: hash, at: index, animated: false) + } + self.hashTypeSelector.selectedSegmentIndex = 0 + + self.outputTypeSelector.removeAllSegments() + self.availableOutputs.enumerated().forEach { (index, output) in + self.outputTypeSelector.insertSegment(withTitle: output, at: index, animated: false) + } + self.outputTypeSelector.selectedSegmentIndex = 0 + } + + @IBAction func didChangeOutputType(_ sender: Any) { + self.updateHashValue() } - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. + @IBAction func didChangeHashType(_ sender: Any) { + self.updateHashValue() + } + + @IBAction func didUpdateField(_ sender: Any) { + self.updateHashValue() + } + + @IBAction func copyHashAction(_ sender: Any) { + UIPasteboard.general.string = self.resultLabel.text + } + + func updateHashValue() { + guard let hashType = HashType.hashType(from: self.hashTypeSelector.selectedSegmentIndex), + let outputType = OutputType.outputType(from: self.outputTypeSelector.selectedSegmentIndex), + let baseText = self.textField.text, !baseText.isEmpty else { + self.resultLabel.text = "Type something." + return + } + self.resultLabel.text = baseText.hasher.hashed(hashType, + output: outputType) } +} +extension HashType { + + static func hashType(from index: Int) -> HashType? { + switch index { + case 0: + return .md5 + case 1: + return .sha1 + case 2: + return .sha224 + case 3: + return .sha256 + case 4: + return .sha384 + case 5: + return .sha512 + default: + return nil + } + } } +extension OutputType { + + static func outputType(from index: Int) -> OutputType? { + switch index { + case 0: + return .hex + case 1: + return .base64 + default: + return nil + } + } +} diff --git a/Example/Podfile b/Example/Podfile index d874c33..559da16 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,12 +1,14 @@ use_frameworks! +platform :ios, '10.0' + target 'Hasher_Example' do pod 'Hasher', :path => '../' target 'Hasher_Tests' do inherit! :search_paths - - pod 'Quick', '~> 1.2.0' - pod 'Nimble', '~> 7.0.2' + + pod 'Quick' + pod 'Nimble' end end diff --git a/Example/Podfile.lock b/Example/Podfile.lock new file mode 100644 index 0000000..298bc7d --- /dev/null +++ b/Example/Podfile.lock @@ -0,0 +1,27 @@ +PODS: + - Hasher (0.1.0) + - Nimble (8.0.0) + - Quick (2.0.0) + +DEPENDENCIES: + - Hasher (from `../`) + - Nimble + - Quick + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Nimble + - Quick + +EXTERNAL SOURCES: + Hasher: + :path: "../" + +SPEC CHECKSUMS: + Hasher: 25a52f7bcd868f67b277c12dc304080e79ab1bc8 + Nimble: a0e6f95b4b91a4f66b6da3512b6bebc07c9cbf49 + Quick: ce1276c7c27ba2da3cb2fd0cde053c3648b3b22d + +PODFILE CHECKSUM: 36409e3c7650be342d99e77c85c385c56097f791 + +COCOAPODS: 1.6.1 diff --git a/Example/Tests/MD5Spec.swift b/Example/Tests/MD5Spec.swift new file mode 100644 index 0000000..493d8c5 --- /dev/null +++ b/Example/Tests/MD5Spec.swift @@ -0,0 +1,62 @@ +// +// MD5Spec.swift +// Hasher_Tests +// +// Created by Andrea Altea on 11/03/2019. +// Copyright © 2019 CocoaPods. All rights reserved. +// + +import Quick +import Nimble +import Hasher + +// Reference hashes got from https://quickhash.com + +class HashMD5Spec: QuickSpec { + override func spec() { + + describe("Hasher") { + context("check MD5 hashes from strings") { + it("Get correct hash as HEX") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.md5()) + .to(equal("cde37111bae8e8de6c360c94739b74f3")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.md5()) + .to(equal("dc20ac6364560cdf00cde343c9ab070c")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.md5()) + .to(equal("78bedad059ff7da5fa74f779fce6a817")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.md5()) + .to(equal("e8396468b43a78f1dbbb7237d312b671")) + expect("People who get violent get that way because they can't communicate.".hasher.md5()) + .to(equal("21750081e86864d32881139b15afb69a")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.md5()) + .to(equal("5a473ffe33375bcaf8d69c36946200bd")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.md5()) + .to(equal("c8a8166c9385a3175ea363c11dfb4f51")) + expect("Life is so much easier when you're numb.".hasher.md5()) + .to(equal("44163d574460ec7171a860adf1f8a890")) + expect("".hasher.md5()).to(equal("d41d8cd98f00b204e9800998ecf8427e")) + } + + it("Get correct hash as base64 encoded") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.md5(.base64)) + .to(equal("zeNxEbro6N5sNgyUc5t08w==")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.md5(.base64)) + .to(equal("3CCsY2RWDN8AzeNDyasHDA==")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.md5(.base64)) + .to(equal("eL7a0Fn/faX6dPd5/OaoFw==")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.md5(.base64)) + .to(equal("6DlkaLQ6ePHbu3I30xK2cQ==")) + expect("People who get violent get that way because they can't communicate.".hasher.md5(.base64)) + .to(equal("IXUAgehoZNMogRObFa+2mg==")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.md5(.base64)) + .to(equal("Wkc//jM3W8r41pw2lGIAvQ==")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.md5(.base64)) + .to(equal("yKgWbJOFoxdeo2PBHftPUQ==")) + expect("Life is so much easier when you're numb.".hasher.md5(.base64)) + .to(equal("RBY9V0Rg7HFxqGCt8fiokA==")) + expect("".hasher.md5(.base64)).to(equal("1B2M2Y8AsgTpgAmY7PhCfg==")) + } + } + } + } +} diff --git a/Example/Tests/SHA1Spec.swift b/Example/Tests/SHA1Spec.swift new file mode 100644 index 0000000..e180569 --- /dev/null +++ b/Example/Tests/SHA1Spec.swift @@ -0,0 +1,62 @@ +// +// SHA1Spec.swift +// Hasher_Tests +// +// Created by Andrea Altea on 11/03/2019. +// Copyright © 2019 CocoaPods. All rights reserved. +// + +import Quick +import Nimble +import Hasher + +// Reference hashes got from https://quickhash.com + +class HashSHA1Spec: QuickSpec { + override func spec() { + + describe("Hasher") { + context("check SHA1 hashes from strings") { + it("Get correct hash as HEX") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.sha1()) + .to(equal("eefecb14f8e213a96772534c76bcc4d07d7ebff2")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.sha1()) + .to(equal("1bfdbdb968bbf19f97153eb8a083f757ce28a78e")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.sha1()) + .to(equal("4edcc94527aa0553005bcda3ab7404e98f0159b0")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.sha1()) + .to(equal("8a0f740646877faa9dfb57ddea5ecda0f529b0c4")) + expect("People who get violent get that way because they can't communicate.".hasher.sha1()) + .to(equal("e0d93b729ecaa45ae1ba4eaf309157b9f9bffb8e")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.sha1()) + .to(equal("d083bc7df97d805d9a1897285a79e1e8b6c054c2")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.sha1()) + .to(equal("7812af01c9df4ea0002ce34dda6756fa5820306c")) + expect("Life is so much easier when you're numb.".hasher.sha1()) + .to(equal("b1e061b9af53918fb9318981275d2c4930702725")) + expect("".hasher.sha1()).to(equal("da39a3ee5e6b4b0d3255bfef95601890afd80709")) + } + + it("Get correct hash as base64 encoded") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.sha1(.base64)) + .to(equal("7v7LFPjiE6lnclNMdrzE0H1+v/I=")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.sha1(.base64)) + .to(equal("G/29uWi78Z+XFT64oIP3V84op44=")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.sha1(.base64)) + .to(equal("TtzJRSeqBVMAW82jq3QE6Y8BWbA=")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.sha1(.base64)) + .to(equal("ig90BkaHf6qd+1fd6l7NoPUpsMQ=")) + expect("People who get violent get that way because they can't communicate.".hasher.sha1(.base64)) + .to(equal("4Nk7cp7KpFrhuk6vMJFXufm/+44=")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.sha1(.base64)) + .to(equal("0IO8ffl9gF2aGJcoWnnh6LbAVMI=")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.sha1(.base64)) + .to(equal("eBKvAcnfTqAALONN2mdW+lggMGw=")) + expect("Life is so much easier when you're numb.".hasher.sha1(.base64)) + .to(equal("seBhua9TkY+5MYmBJ10sSTBwJyU=")) + expect("".hasher.sha1(.base64)).to(equal("2jmj7l5rSw0yVb/vlWAYkK/YBwk=")) + } + } + } + } +} diff --git a/Example/Tests/SHA256Spec.swift b/Example/Tests/SHA256Spec.swift new file mode 100644 index 0000000..559c4b7 --- /dev/null +++ b/Example/Tests/SHA256Spec.swift @@ -0,0 +1,63 @@ +// +// SHA256Spec.swift +// Hasher_Example +// +// Created by Andrea Altea on 11/03/2019. +// Copyright © 2019 CocoaPods. All rights reserved. +// + +import Quick +import Nimble +import Hasher + +// Reference hashes got from https://quickhash.com + +class HashSpec: QuickSpec { + override func spec() { + + describe("Hasher") { + context("check SHA256 hashes from strings") { + it("Get correct hash as HEX") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.sha256()) + .to(equal("c0e06cb3f649311480ec0d4420600c1b3ce56375c1e9bff5d851ca5e7299a8bd")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.sha256()) + .to(equal("866a67192923d88a851612359d7fc90d749131e2da8cbb5b7c125178e5a481a8")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.sha256()) + .to(equal("bea00e008e87435a2436decb5a51c2d70627e2d6567856ed3233917be9bfc787")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.sha256()) + .to(equal("e329e343e9e6aa800dc0e598163365005ca250a076d06fc51826ad94383c6978")) + expect("People who get violent get that way because they can't communicate.".hasher.sha256()) + .to(equal("6bdf930979291fb8c1dc85303a85e5aec689147fa925023d8ed93a5263aa5d00")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.sha256()) + .to(equal("97657b1bf7e4b256fb672eb4928f4fcc2aa63b35956a35a7ae0e953141d84a5e")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.sha256()) + .to(equal("ab01dbf11103ba2a3a5f147dd1fc944cbdda135f630214e898978cdf03e94c2e")) + expect("Life is so much easier when you're numb.".hasher.sha256()) + .to(equal("06f4ae45868b8710f350d8a2ff0d8f243e8fe9b22d9e1c2671175b196d45f8e0")) + expect("".hasher.sha256()).to(equal("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")) + } + + it("Get correct hash as base64 encoded") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.sha256(.base64)) + .to(equal("wOBss/ZJMRSA7A1EIGAMGzzlY3XB6b/12FHKXnKZqL0=")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.sha256(.base64)) + .to(equal("hmpnGSkj2IqFFhI1nX/JDXSRMeLajLtbfBJReOWkgag=")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.sha256(.base64)) + .to(equal("vqAOAI6HQ1okNt7LWlHC1wYn4tZWeFbtMjORe+m/x4c=")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.sha256(.base64)) + .to(equal("4ynjQ+nmqoANwOWYFjNlAFyiUKB20G/FGCatlDg8aXg=")) + expect("People who get violent get that way because they can't communicate.".hasher.sha256(.base64)) + .to(equal("a9+TCXkpH7jB3IUwOoXlrsaJFH+pJQI9jtk6UmOqXQA=")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.sha256(.base64)) + .to(equal("l2V7G/fkslb7Zy60ko9PzCqmOzWVajWnrg6VMUHYSl4=")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.sha256(.base64)) + .to(equal("qwHb8REDuio6XxR90fyUTL3aE19jAhTomJeM3wPpTC4=")) + expect("Life is so much easier when you're numb.".hasher.sha256(.base64)) + .to(equal("BvSuRYaLhxDzUNii/w2PJD6P6bItnhwmcRdbGW1F+OA=")) + expect("".hasher.sha256(.base64)).to(equal("47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")) + } + } + + } + } +} diff --git a/Example/Tests/SHA512Spec copy.swift b/Example/Tests/SHA512Spec copy.swift new file mode 100644 index 0000000..94fabe6 --- /dev/null +++ b/Example/Tests/SHA512Spec copy.swift @@ -0,0 +1,63 @@ +// +// SHA512Spec.swift +// Hasher_Example +// +// Created by Andrea Altea on 11/03/2019. +// Copyright © 2019 CocoaPods. All rights reserved. +// + +import Quick +import Nimble +import Hasher + +// Reference hashes got from https://quickhash.com + +class HashSHA512Spec: QuickSpec { + override func spec() { + + describe("Hasher") { + context("check SHA512 hashes from strings") { + it("Get correct hash as HEX") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.sha512()) + .to(equal("082fcbf38d1b4ab45aa558c4b45d2b71806d85eb191040e8975900750725c40155e6d762c080d6a9e1aed843c38dba64c035f52db17eef83d0ce200d69757dfd")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.sha512()) + .to(equal("8a3a44ddbd982328fd356abbbdcd4861f2d72c84ff85c3c4ff66ce8d95930dc5d054406878275f84944cfed012152e96475be91040e9e7e618c948aa566597c7")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.sha512()) + .to(equal("cdacb36fb702d1b49b5ed8487d9b176ae4f3b7667a414debb5abf75166299e58cda512487cd7eba2225fe56d9651829d3f324efe8ddc0d0c48352e62654a0412")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.sha512()) + .to(equal("322cfcab8f451789c9c2e0d3aeb2d0ad25a08d169e9bc5dd0b47c1e78e1a0913db7bdb5673fd90d4040e12072c248d99f2fe7006b81282abe27480fd130a670d")) + expect("People who get violent get that way because they can't communicate.".hasher.sha512()) + .to(equal("c66ad7f1d3f208f736d632aba0b77e5f3671c5365d64e30d5ee75ec18fa33c4addc2c0c262c7a00fb50fd1e81ec8597fae1064981744052c0bb37e3ab30ac960")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.sha512()) + .to(equal("6e96d3b32454c59edfe739e325370d31c8839c5bd1251e481365dd55ef2c50b7bc4bcdb7ea97572c493c865f56b7732c954327042efbe34a489c1ac416bd6def")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.sha512()) + .to(equal("6a699a30eb602cee02653343e6bb648516fc142a8d2295f6f14ac242b8cf24894dc0df59cc03da2c9c9f468b9a52a60c8ac61d19622bbe0ee0046330494d89a3")) + expect("Life is so much easier when you're numb.".hasher.sha512()) + .to(equal("9972004e5ca45d11a1c832b5cd7fc2e6be508396c38f30163ddac4524efb631860dcb8b15c7ff076a25d65ff2cd92c74bc4044c4392a9c8b086459f60719f02b")) + expect("".hasher.sha512()).to(equal("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")) + } + + it("Get correct hash as base64 encoded") { + expect("Hello friend. Hello friend? That's lame. Maybe I should give you a name.".hasher.sha512(.base64)) + .to(equal("CC/L840bSrRapVjEtF0rcYBthesZEEDol1kAdQclxAFV5tdiwIDWqeGu2EPDjbpkwDX1LbF+74PQziANaXV9/Q==")) + expect("The douche I was dating proposed to me, can you believe? I mean, what an asshole.".hasher.sha512(.base64)) + .to(equal("ijpE3b2YIyj9NWq7vc1IYfLXLIT/hcPE/2bOjZWTDcXQVEBoeCdfhJRM/tASFS6WR1vpEEDp5+YYyUiqVmWXxw==")) + expect("That neat little ditty was Trenton's idea. She may look innocent, but I'd be careful. She's got some Allah Akbar in her.".hasher.sha512(.base64)) + .to(equal("zayzb7cC0bSbXthIfZsXauTzt2Z6QU3rtav3UWYpnljNpRJIfNfroiJf5W2WUYKdPzJO/o3cDQxINS5iZUoEEg==")) + expect("The world is a dangerous place, Elliot, not because of those who do evil, but because of those who look on and do nothing.".hasher.sha512(.base64)) + .to(equal("Miz8q49FF4nJwuDTrrLQrSWgjRaem8XdC0fB544aCRPbe9tWc/2Q1AQOEgcsJI2Z8v5wBrgSgqvidID9EwpnDQ==")) + expect("People who get violent get that way because they can't communicate.".hasher.sha512(.base64)) + .to(equal("xmrX8dPyCPc21jKroLd+XzZxxTZdZOMNXudewY+jPErdwsDCYsegD7UP0egeyFl/rhBkmBdEBSwLs346swrJYA==")) + expect("Shit. I'm gonna have to let him hug me, aren't I?".hasher.sha512(.base64)) + .to(equal("bpbTsyRUxZ7f5znjJTcNMciDnFvRJR5IE2XdVe8sULe8S8236pdXLEk8hl9Wt3MslUMnBC7740pInBrEFr1t7w==")) + expect("True courage is about being honest with yourself. Especially when it's difficult.".hasher.sha512(.base64)) + .to(equal("ammaMOtgLO4CZTND5rtkhRb8FCqNIpX28UrCQrjPJIlNwN9ZzAPaLJyfRouaUqYMisYdGWIrvg7gBGMwSU2Jow==")) + expect("Life is so much easier when you're numb.".hasher.sha512(.base64)) + .to(equal("mXIATlykXRGhyDK1zX/C5r5Qg5bDjzAWPdrEUk77Yxhg3LixXH/wdqJdZf8s2Sx0vEBExDkqnIsIZFn2BxnwKw==")) + expect("".hasher.sha512(.base64)).to(equal("z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==")) + } + } + + } + } +} diff --git a/Example/Tests/Tests.swift b/Example/Tests/Tests.swift deleted file mode 100644 index b536b6c..0000000 --- a/Example/Tests/Tests.swift +++ /dev/null @@ -1,50 +0,0 @@ -// https://github.com/Quick/Quick - -import Quick -import Nimble -import Hasher - -class TableOfContentsSpec: QuickSpec { - override func spec() { - describe("these will fail") { - - it("can do maths") { - expect(1) == 2 - } - - it("can read") { - expect("number") == "string" - } - - it("will eventually fail") { - expect("time").toEventually( equal("done") ) - } - - context("these will pass") { - - it("can do maths") { - expect(23) == 23 - } - - it("can read") { - expect("🐮") == "🐮" - } - - it("will eventually pass") { - var time = "passing" - - DispatchQueue.main.async { - time = "done" - } - - waitUntil { done in - Thread.sleep(forTimeInterval: 0.5) - expect(time) == "done" - - done() - } - } - } - } - } -} diff --git a/Hasher/Classes/ReplaceMe.swift b/Example/fastlane/Appfile similarity index 100% rename from Hasher/Classes/ReplaceMe.swift rename to Example/fastlane/Appfile diff --git a/Example/fastlane/Fastfile b/Example/fastlane/Fastfile new file mode 100644 index 0000000..fcccc14 --- /dev/null +++ b/Example/fastlane/Fastfile @@ -0,0 +1,72 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +update_fastlane + +default_platform(:ios) + +platform :ios do + + desc "Default CI lane" + lane :ci do + update_dependencies + pod_lint + test + coverage + end + + desc "Update dependencies" + lane :update_dependencies do + cocoapods( + repo_update: true + ) + end + + desc "Pod lib lint" + lane :pod_lint do + Dir.chdir("../..") do + sh("pod lib lint") + end + end + + desc "Runs all the tests" + lane :test do + scan( + scheme: "Hasher-Example", + device: "iPhone XS", + code_coverage: true + ) + end + + desc "Slather sends coverage to Coveralls" + lane :coverage do + slather( + travis: true, + workspace: "Hasher.xcworkspace", + proj: "Hasher.xcodeproj", + scheme: "Hasher-Example", + binary_basename: "Hasher", + source_directory: "../Hasher/*", + simple_output: true, + coveralls: true + ) + end + + desc "Clean environment after all operations" + lane :clean do + clean_build_artifacts + end + + after_all do |lane| + clean + end +end \ No newline at end of file diff --git a/Example/fastlane/README.md b/Example/fastlane/README.md new file mode 100644 index 0000000..5f077bf --- /dev/null +++ b/Example/fastlane/README.md @@ -0,0 +1,54 @@ +fastlane documentation +================ +# Installation + +Make sure you have the latest version of the Xcode command line tools installed: + +``` +xcode-select --install +``` + +Install _fastlane_ using +``` +[sudo] gem install fastlane -NV +``` +or alternatively using `brew cask install fastlane` + +# Available Actions +## iOS +### ios ci +``` +fastlane ios ci +``` +Default CI lane +### ios lint +``` +fastlane ios lint +``` +SwiftLint linting +### ios pod_lint +``` +fastlane ios pod_lint +``` +Pod lib lint +### ios test +``` +fastlane ios test +``` +Runs all the tests +### ios coverage +``` +fastlane ios coverage +``` +Slather sends coverage to Coveralls +### ios clean +``` +fastlane ios clean +``` +Clean environment after all operations + +---- + +This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. +More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). +The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). \ No newline at end of file diff --git a/Hasher.podspec b/Hasher.podspec index 3e9def7..bd8df2c 100644 --- a/Hasher.podspec +++ b/Hasher.podspec @@ -9,34 +9,22 @@ Pod::Spec.new do |s| s.name = 'Hasher' s.version = '0.1.0' - s.summary = 'A short description of Hasher.' - -# This description is used to generate tags and improve search results. -# * Think: What does it do? Why did you write it? What is the focus? -# * Try to keep it short, snappy and to the point. -# * Write the description between the DESC delimiters below. -# * Finally, don't worry about the indent, CocoaPods strips it! + s.summary = 'A simple Hashing library.' + s.swift_version = '4.3' s.description = <<-DESC -TODO: Add long description of the pod here. +A wrapper around CommonCrypto to calculate Hashes of various objects. DESC - s.homepage = 'https://github.com/acct=/Hasher' - # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' + s.homepage = 'https://github.com/Oni-zerone/Hasher' s.license = { :type => 'MIT', :file => 'LICENSE' } - s.author = { 'acct=' => 'oni.zerone@gmail.com' } - s.source = { :git => 'https://github.com/acct=/Hasher.git', :tag => s.version.to_s } - # s.social_media_url = 'https://twitter.com/' + s.author = { 'Andrea Altea' => 'oni.zerone@gmail.com' } + s.source = { :git => 'https://github.com/Oni-zerone/Hasher.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/Oni_zerone' - s.ios.deployment_target = '8.0' + s.ios.deployment_target = '10.0' s.source_files = 'Hasher/Classes/**/*' - - # s.resource_bundles = { - # 'Hasher' => ['Hasher/Assets/*.png'] - # } - # s.public_header_files = 'Pod/Classes/**/*.h' - # s.frameworks = 'UIKit', 'MapKit' - # s.dependency 'AFNetworking', '~> 2.3' + s.frameworks = 'Foundation' end diff --git a/Hasher/Classes/Hasher.swift b/Hasher/Classes/Hasher.swift new file mode 100644 index 0000000..86e0ad7 --- /dev/null +++ b/Hasher/Classes/Hasher.swift @@ -0,0 +1,95 @@ +// +// Hasher.swift +// Hasher +// +// Created by Andrea Altea on 09/03/2019. +// + +import Foundation +import CommonCrypto + +public struct Hasher { + + public let data: Data? + + public init(_ data: Data?) { + self.data = data + } +} + +public extension Hasher { + + /// Hashing algorithm that prepends an RSA2048ASN1Header to the beginning of the data being hashed. + /// + /// - Parameters: + /// - type: The type of hash algorithm to use for the hashing operation. + /// - output: The type of output string desired. + /// - Returns: A hash string using the specified hashing algorithm, or nil. + func hashWithRSA2048Asn1Header(_ type: HashType, output: OutputType = .hex) -> String? { + + guard let data = self.data else { return nil } + + let rsa2048Asn1Header:[UInt8] = [ + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00 + ] + + var headerData = Data(bytes: rsa2048Asn1Header) + headerData.append(data) + return hashed(type, output: output) + } + + /// Hashing algorithm for hashing a Data instance. + /// + /// - Parameters: + /// - type: The type of hash to use. + /// - output: The type of hash output desired, defaults to .hex. + /// - Returns: The requested hash output or nil if failure. + func hashed(_ type: HashType, output: OutputType) -> String? { + + guard let data = self.data else { return nil } + + var digest = Data(count: Int(type.length)) + _ = digest.withUnsafeMutableBytes { (digestBytes: UnsafeMutablePointer) in + data.withUnsafeBytes { (messageBytes: UnsafePointer) in + let length = CC_LONG(data.count) + switch type { + case .md5: CC_MD5(messageBytes, length, digestBytes) + case .sha1: CC_SHA1(messageBytes, length, digestBytes) + case .sha224: CC_SHA224(messageBytes, length, digestBytes) + case .sha256: CC_SHA256(messageBytes, length, digestBytes) + case .sha384: CC_SHA384(messageBytes, length, digestBytes) + case .sha512: CC_SHA512(messageBytes, length, digestBytes) + } + } + } + return output.parse(from: digest) + } +} + +public extension Hasher { + + func md5(_ output: OutputType = .hex) -> String? { + return self.hashed(.md5, output: output) + } + + func sha1(_ output: OutputType = .hex) -> String? { + return self.hashed(.sha1, output: output) + } + + func sha224(_ output: OutputType = .hex) -> String? { + return self.hashed(.sha224, output: output) + } + + func sha256(_ output: OutputType = .hex) -> String? { + return self.hashed(.sha256, output: output) + } + + func sha384(_ output: OutputType = .hex) -> String? { + return self.hashed(.sha384, output: output) + } + + func sha512(_ output: OutputType = .hex) -> String? { + return self.hashed(.sha512, output: output) + } +} diff --git a/Hasher/Classes/HasherCompatible.swift b/Hasher/Classes/HasherCompatible.swift new file mode 100644 index 0000000..41d635f --- /dev/null +++ b/Hasher/Classes/HasherCompatible.swift @@ -0,0 +1,40 @@ +// +// Hasher+Data.swift +// Hasher +// +// Created by Andrea Altea on 08/03/2019. +// + +import Foundation + +public protocol HasherCompatible { + + associatedtype CompatibleType + + var hasher: Hasher { get } + + var hasher_data: Data? { get } +} + +extension HasherCompatible { + + public var hasher: Hasher { + return Hasher(self.hasher_data) + } +} + +extension String: HasherCompatible { + public typealias CompatibleType = String + + public var hasher_data: Data? { + return self.data(using: .utf8) + } +} + +extension Data: HasherCompatible { + public typealias CompatibleType = Data + + public var hasher_data: Data? { + return self + } +} diff --git a/Hasher/Classes/Interfaces/HasherType.swift b/Hasher/Classes/Interfaces/HasherType.swift new file mode 100644 index 0000000..5f327b2 --- /dev/null +++ b/Hasher/Classes/Interfaces/HasherType.swift @@ -0,0 +1,33 @@ +// +// HasherType.swift +// Hasher +// +// Created by Andrea Altea on 08/03/2019. +// + +import Foundation +import CommonCrypto + +// Defines types of hash algorithms available +public enum HashType { + case md5 + case sha1 + case sha224 + case sha256 + case sha384 + case sha512 +} + +extension HashType { + + var length: Int32 { + switch self { + case .md5: return CC_MD5_DIGEST_LENGTH + case .sha1: return CC_SHA1_DIGEST_LENGTH + case .sha224: return CC_SHA224_DIGEST_LENGTH + case .sha256: return CC_SHA256_DIGEST_LENGTH + case .sha384: return CC_SHA384_DIGEST_LENGTH + case .sha512: return CC_SHA512_DIGEST_LENGTH + } + } +} diff --git a/Hasher/Classes/Interfaces/OutputType.swift b/Hasher/Classes/Interfaces/OutputType.swift new file mode 100644 index 0000000..bf7d2b8 --- /dev/null +++ b/Hasher/Classes/Interfaces/OutputType.swift @@ -0,0 +1,27 @@ +// +// OutputType.swift +// Hasher +// +// Created by Andrea Altea on 08/03/2019. +// + +import Foundation + +// Defines types of hash string outputs available +public enum OutputType { + // standard hex string output + case hex + // base 64 encoded string output + case base64 +} + +extension OutputType { + + func parse(from digest: Data) -> String { + + switch self { + case .hex: return digest.map { String(format: "%02hhx", $0) }.joined() + case .base64: return digest.base64EncodedString() + } + } +} diff --git a/README.md b/README.md index 513c98d..4f431c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -# Hasher - -[![CI Status](https://img.shields.io/travis/acct=/Hasher.svg?style=flat)](https://travis-ci.org/acct=/Hasher) +Miss Electric Eel 2016 Hasher +====================================== +[![Build Status](https://travis-ci.com/Oni-zerone/Hasher.svg?branch=develop)](https://travis-ci.com/Oni-zerone/Hasher) +[![Coverage Status](https://coveralls.io/repos/github/Oni-zerone/Hasher/badge.svg?branch=develop)](https://coveralls.io/github/Oni-zerone/Hasher?branch=develop) [![Version](https://img.shields.io/cocoapods/v/Hasher.svg?style=flat)](https://cocoapods.org/pods/Hasher) [![License](https://img.shields.io/cocoapods/l/Hasher.svg?style=flat)](https://cocoapods.org/pods/Hasher) [![Platform](https://img.shields.io/cocoapods/p/Hasher.svg?style=flat)](https://cocoapods.org/pods/Hasher) diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..2cf0d23 Binary files /dev/null and b/logo.png differ