এখানে অন্যান্য উত্তরগুলি পড়ার পরে (এবং পাশাপাশি অন্যান্য হ্যাশ ধরণের সমর্থন করা প্রয়োজন) আমি একটি স্ট্রিং এক্সটেনশন লিখেছিলাম যা একাধিক হ্যাশ ধরণের এবং আউটপুট প্রকারগুলি পরিচালনা করে।
দ্রষ্টব্য: কমনক্রিপ্টোটি এক্সকোড 10 এ অন্তর্ভুক্ত করা হয়েছে, সুতরাং আপনি import CommonCrypto
যদি সর্বশেষে এক্সকোড সংস্করণ ইনস্টল করেন তবে ব্রিজিং শিরোনামের সাথে গোলমাল না করেই আপনি পারবেন ... অন্যথায় একটি ব্রিজিং শিরোলেখ প্রয়োজনীয়।
আপডেট: সুইফট 4 এবং 5 উভয়ই নীচে একই স্ট্রিং + ক্রিপ্টো.সুইফ্ট ফাইল ব্যবহার করে।
সুইফট 5 এবং 5 এর মধ্যে পরিবর্তিত 'উইনস্যাফমুটেবলবাইটস' এবং 'উইথ ইউনসেফবাইটস' এর এপিআই হিসাবে সুইফট 5 (নীচে দেখুন) এর জন্য আলাদা তথ্য + ক্রিপ্টো.সুইফ্ট ফাইল রয়েছে।
স্ট্রিং + ক্রিপ্টো.সুইফ্ট - (সুইফট 4 এবং 5 উভয়ের জন্য)
import Foundation
import CommonCrypto
// Defines types of hash string outputs available
public enum HashOutputType {
// standard hex string output
case hex
// base 64 encoded string output
case base64
}
// Defines types of hash algorithms available
public enum HashType {
case md5
case sha1
case sha224
case sha256
case sha384
case sha512
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
}
}
}
public extension String {
/// Hashing algorithm for hashing a string instance.
///
/// - Parameters:
/// - type: The type of hash to use.
/// - output: The type of output desired, defaults to .hex.
/// - Returns: The requested hash output or nil if failure.
public func hashed(_ type: HashType, output: HashOutputType = .hex) -> String? {
// convert string to utf8 encoded data
guard let message = data(using: .utf8) else { return nil }
return message.hashed(type, output: output)
}
}
সুইফট 5 - ডেটা + ক্রিপ্টো.সুইফ্ট
import Foundation
import CommonCrypto
extension Data {
/// 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.
public func hashWithRSA2048Asn1Header(_ type: HashType, output: HashOutputType = .hex) -> String? {
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(rsa2048Asn1Header)
headerData.append(self)
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.
public func hashed(_ type: HashType, output: HashOutputType = .hex) -> String? {
// setup data variable to hold hashed value
var digest = Data(count: Int(type.length))
_ = digest.withUnsafeMutableBytes{ digestBytes -> UInt8 in
self.withUnsafeBytes { messageBytes -> UInt8 in
if let mb = messageBytes.baseAddress, let db = digestBytes.bindMemory(to: UInt8.self).baseAddress {
let length = CC_LONG(self.count)
switch type {
case .md5: CC_MD5(mb, length, db)
case .sha1: CC_SHA1(mb, length, db)
case .sha224: CC_SHA224(mb, length, db)
case .sha256: CC_SHA256(mb, length, db)
case .sha384: CC_SHA384(mb, length, db)
case .sha512: CC_SHA512(mb, length, db)
}
}
return 0
}
}
// return the value based on the specified output type.
switch output {
case .hex: return digest.map { String(format: "%02hhx", $0) }.joined()
case .base64: return digest.base64EncodedString()
}
}
}
সুইফট 4 - ডেটা + ক্রিপ্টো.সুইফ্ট
import Foundation
import CommonCrypto
extension Data {
/// 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.
public func hashWithRSA2048Asn1Header(_ type: HashType, output: HashOutputType = .hex) -> String? {
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(self)
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.
public func hashed(_ type: HashType, output: HashOutputType = .hex) -> String? {
// setup data variable to hold hashed value
var digest = Data(count: Int(type.length))
// generate hash using specified hash type
_ = digest.withUnsafeMutableBytes { (digestBytes: UnsafeMutablePointer<UInt8>) in
self.withUnsafeBytes { (messageBytes: UnsafePointer<UInt8>) in
let length = CC_LONG(self.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 the value based on the specified output type.
switch output {
case .hex: return digest.map { String(format: "%02hhx", $0) }.joined()
case .base64: return digest.base64EncodedString()
}
}
}
সম্পাদনা করুন: যেহেতু হ্যাশটি ডেটাতে আসলে ঘটে তাই আমি হ্যাশিং অ্যালগরিদমকে ডেটা এক্সটেনশনে বিভক্ত করি। এটি এসএসএল শংসাপত্রের পিনিং হ্যাশ ক্রিয়াকলাপগুলির জন্য একই অ্যালগরিদমকেও ব্যবহার করতে দেয়।
আপনি কীভাবে এটি একটি এসএসএল পিনিং অপারেশনের জন্য ব্যবহার করতে পারেন তার একটি সংক্ষিপ্ত উদাহরণ এখানে:
// Certificate pinning - get certificate as data
let data: Data = SecCertificateCopyData(serverCertificate) as Data
// compare hash of server certificate with local (expected) hash value
guard let serverHash = data.hashWithRSA2048Asn1Header(.sha256, output: .base64), serverHash == storedHash else {
print("SSL PINNING: Server certificate hash does not match specified hash value.")
return false
}
মূল উত্তর ফিরে
আমি এটি ব্যবহার করে হ্যাশ অ্যালগরিদমগুলি পরীক্ষা করেছি:
let value = "This is my string"
if let md5 = value.hashed(.md5) {
print("md5: \(md5)")
}
if let sha1 = value.hashed(.sha1) {
print("sha1: \(sha1)")
}
if let sha224 = value.hashed(.sha224) {
print("sha224: \(sha224)")
}
if let sha256 = value.hashed(.sha256) {
print("sha256: \(sha256)")
}
if let sha384 = value.hashed(.sha384) {
print("sha384: \(sha384)")
}
if let sha512 = value.hashed(.sha512) {
print("sha512: \(sha512)")
}
এবং এটি মুদ্রিত ফলাফল:
md5: c2a9ce57e8df081b4baad80d81868bbb
sha1: 37fb219bf98bee51d2fdc3ba6d866c97f06c8223
sha224: f88e2f20aa89fb4dffb6bdc62d7bd75e1ba02574fae4a437c3bf49c7
sha256: 9da6c02379110815278b615f015f0b254fd3d5a691c9d8abf8141655982c046b
sha384: d9d7fc8aefe7f8f0a969b132a59070836397147338e454acc6e65ca616099d03a61fcf9cc8c4d45a2623145ebd398450
sha512: 349cc35836ba85915ace9d7f895b712fe018452bb4b20ff257257e12adeb1e83ad780c6568a12d03f5b2cb1e3da23b8b7ced9012a188ef3855e0a8f3db211883