Swift 中使用 SHA512 的哈希字符串

2024-01-07

有人知道如何在 swift 中重现 PHP 哈希方法 hash('SHA512', $value, true) 吗?我尝试将 CommonCrypto C 库与以下代码一起使用:

extension String {
    func digest(length:Int32, gen:(data: UnsafePointer<Void>, len: CC_LONG, md: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8>) -> String {
        var cStr = [UInt8](self.utf8)
        var result = [UInt8](count:Int(length), repeatedValue:0)
        gen(data: &cStr, len: CC_LONG(cStr.count), md: &result)
        let output = NSMutableString(capacity:Int(length))
        for r in result {
            output.appendFormat("%02x", r)
        }
        return String(output)
    }
}

并像这样使用它:

var digest = salted.digest(CC_SHA512_DIGEST_LENGTH, gen: {(data, len, md) in CC_SHA512(data,len,md)})

但我没有得到正确的输出

EDIT :

我有一些 PHP 代码:

echo base64_encode(hash('sha512', '8yOrBmkd', true)); // output: rlltLWeWaQCrfNTYMa0CcIs0mfLoHGAynrd+d8H65+rGAzHS/BSWsumwSmcxF9aAG9TIzXx+HOjArPyLL3herg==

我希望我的快速代码能够输出相同的结果。 Base64 编码没问题:

let utf8str = input.dataUsingEncoding(NSUTF8StringEncoding)!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
                let base64Encoded = utf8str!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
                print("Encoded:  \(base64Encoded)")

但哈希部分返回的输出值与此 PHP 代码相同:

echo base64_encode(hash('sha512', '8yOrBmkd', false)); // output: YWU1OTZkMmQ2Nzk2NjkwMGFiN2NkNGQ4MzFhZDAyNzA4YjM0OTlmMmU4MWM2MDMyOWViNzdlNzdjMWZhZTdlYWM2MDMzMWQyZmMxNDk2YjJlOWIwNGE2NzMxMTdkNjgwMWJkNGM4Y2Q3YzdlMWNlOGMwYWNmYzhiMmY3ODVlYWU=

Swift 3 实现在底部。

代码不需要那么复杂或者扩展:

func sha512Hex(string string: String) -> String {
    var digest = [UInt8](count: Int(CC_SHA512_DIGEST_LENGTH), repeatedValue: 0)
    if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
        CC_SHA512(data.bytes, CC_LONG(data.length), &digest)
    }

    var digestHex = ""
    for index in 0..<Int(CC_SHA512_DIGEST_LENGTH) {
        digestHex += String(format: "%02x", digest[index])
    }

    return digestHex
}

//测试:

let hexDigest = sha512Hex(string:"8yOrBmkd")
print("hexDigest:\n\(hexDigest)")

Output:

十六进制摘要: ae596d2d67966900ab7cd4d831ad02708b3499f2e81c60329eb77e77c1fae7eac60331d2fc1496b2e9b04a673117d6801bd4c8cd7c7e1ce8c0acfc8b2f785eae

仅返回字节数组:

func sha512(string string: String) -> [UInt8] {
    var digest = [UInt8](count: Int(CC_SHA512_DIGEST_LENGTH), repeatedValue: 0)
    let data = string.dataUsingEncoding(NSUTF8StringEncoding)!
    CC_SHA512(data.bytes, CC_LONG(data.length), &digest)

    return digest
}

//Test:

let digestRaw = sha512(string:"8yOrBmkd")
print("decimal array:\n\(digestRaw)")
print("hexadecimal:\n\(NSData(bytes:digestRaw, length:digestRaw.count).description)")

输出:

十进制数组: [174, 89, 109, 45, 103, 150, 105, 0, 171, 124, 212, 216, 49, 173, 2, 112, 139, 52, 153, 242, 232, 28, 96, 50, 158 , 183, 126, 119, 193, 250, 231, 234, 198, 3, 49, 210, 252, 20, 150, 178, 233, 176, 74, 103, 49, 23, 214, 128, 27, 212 , 200, 205, 124, 126, 28, 232, 192, 172, 252, 139, 47, 120, 94, 174]

十六进制:
ae596d2d67966900ab7cd4d831ad02708b3499f2e81c60329eb77e77c1fae7eac60331d2fc1496b2e9b04a673117d6801bd4c8cd7c7e1ce8c0acfc8b2f785eae

Base64 输出:

func sha512Base64(string string: String) -> String {
    let digest = NSMutableData(length: Int(CC_SHA512_DIGEST_LENGTH))!
    if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
        CC_SHA512(data.bytes, CC_LONG(data.length), UnsafeMutablePointer<UInt8>(digest.mutableBytes))
    }
    return digest.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
}

//测试:

let digestBase64 = sha512Base64(string:"8yOrBmkd")
print("Base64:\n\(digestBase64)")

Output:

Base64: rlltLWeWaQCrfNTYMa0CcIs0mfLoHGAynrd+d8H65+rGAzHS/BSWsumwSmcxF9aAG9TIzXx+HOjArPyLL3herg==

Swift 3

func hashSHA512(data:Data) -> String? {
    var hashData = Data(count: Int(CC_SHA512_DIGEST_LENGTH))

    _ = hashData.withUnsafeMutableBytes {digestBytes in
        data.withUnsafeBytes {messageBytes in
            CC_SHA512(messageBytes, CC_LONG(data.count), digestBytes)
        }
    }

    // For hexadecimal output:
    return hashData.map { String(format: "%02hhx", $0) }.joined()
    // For Base64 output use this instead of the above:
    // return data.base64EncodedString()
}

已弃用文档部分的示例:

具有 MD5、SHA1、SHA224、SHA256、SHA384、SHA512 的 HMAC(Swift 3+)

这些函数将使用八种加密哈希算法之一对字符串或数据输入进行哈希处理。

name 参数将哈希函数名称指定为字符串 支持的函数有 MD5、SHA1、SHA224、SHA256、SHA384 和 SHA512

此示例需要通用加密货币
项目必须有一个桥接头:
#import <CommonCrypto/CommonCrypto.h>
将 Security.framework 添加到项目中。

这些函数采用哈希名称、要哈希的消息、密钥并返回摘要:




hashName: name of a hash function as String  
message:  message as Data  
key:      key as Data  
returns:  digest as Data  
  
func hmac(hashName:String, message:Data, key:Data) -> Data? {
    let algos = ["SHA1":   (kCCHmacAlgSHA1,   CC_SHA1_DIGEST_LENGTH),
                 "MD5":    (kCCHmacAlgMD5,    CC_MD5_DIGEST_LENGTH),
                 "SHA224": (kCCHmacAlgSHA224, CC_SHA224_DIGEST_LENGTH),
                 "SHA256": (kCCHmacAlgSHA256, CC_SHA256_DIGEST_LENGTH),
                 "SHA384": (kCCHmacAlgSHA384, CC_SHA384_DIGEST_LENGTH),
                 "SHA512": (kCCHmacAlgSHA512, CC_SHA512_DIGEST_LENGTH)]
    guard let (hashAlgorithm, length) = algos[hashName]  else { return nil }
    var macData = Data(count: Int(length))

    macData.withUnsafeMutableBytes {macBytes in
        message.withUnsafeBytes {messageBytes in
            key.withUnsafeBytes {keyBytes in
                CCHmac(CCHmacAlgorithm(hashAlgorithm),
                       keyBytes,     key.count,
                       messageBytes, message.count,
                       macBytes)
            }
        }
    }
    return macData

}



hashName: name of a hash function as String
message:  message as String
key:      key as String
returns:  digest as Data
  
func hmac(hashName:String, message:String, key:String) -> Data? {
    let messageData = message.data(using:.utf8)!
    let keyData = key.data(using:.utf8)!
    return hmac(hashName:hashName, message:messageData, key:keyData)
}



hashName: name of a hash function as String  
message:  message as String  
key:      key as Data  
returns:  digest as Data  
  
func hmac(hashName:String, message:String, key:Data) -> Data? {
    let messageData = message.data(using:.utf8)!
    return hmac(hashName:hashName, message:messageData, key:key)
}

// 例子

let clearString = "clearData0123456"
let keyString   = "keyData8901234562"
let clearData   = clearString.data(using:.utf8)!
let keyData     = keyString.data(using:.utf8)!
print("clearString: \(clearString)")
print("keyString:   \(keyString)")
print("clearData: \(clearData as NSData)")
print("keyData:   \(keyData as NSData)")

let hmacData1 = hmac(hashName:"SHA1", message:clearData, key:keyData)
print("hmacData1: \(hmacData1! as NSData)")

let hmacData2 = hmac(hashName:"SHA1", message:clearString, key:keyString)
print("hmacData2: \(hmacData2! as NSData)")

let hmacData3 = hmac(hashName:"SHA1", message:clearString, key:keyData)
print("hmacData3: \(hmacData3! as NSData)")

Output:

clearString: clearData0123456
keyString:   keyData8901234562
clearData: <636c6561 72446174 61303132 33343536>
keyData:   <6b657944 61746138 39303132 33343536 32>

hmacData1: <bb358f41 79b68c08 8e93191a da7dabbc 138f2ae6>
hmacData2: <bb358f41 79b68c08 8e93191a da7dabbc 138f2ae6>
hmacData3: <bb358f41 79b68c08 8e93191a da7dabbc 138f2ae6>

MD2、MD4、MD5、SHA1、SHA224、SHA256、SHA384、SHA512(Swift 3+)

这些函数将使用八种加密哈希算法之一对字符串或数据输入进行哈希处理。

name 参数将哈希函数名称指定为字符串
支持的函数有 MD2、MD4、MD5、SHA1、SHA224、SHA256、SHA384 和 SHA512 A 此示例需要通用加密货币
项目必须有一个桥接头:
#import <CommonCrypto/CommonCrypto.h>
将 Security.framework 添加到项目中。



该函数采用哈希名称和要进行哈希处理的字符串并返回数据:



name: A name of a hash function as a String  
string: The String to be hashed  
returns: the hashed result as Data  
  
func hash(name:String, string:String) -> Data? {
    let data = string.data(using:.utf8)!
    return hash(name:name, data:data)
}

例子:

let clearString = "clearData0123456"
let clearData   = clearString.data(using:.utf8)!
print("clearString: \(clearString)")
print("clearData: \(clearData as NSData)")

let hashSHA256 = hash(name:"SHA256", string:clearString)
print("hashSHA256: \(hashSHA256! as NSData)")

let hashMD5 = hash(name:"MD5", data:clearData)
print("hashMD5: \(hashMD5! as NSData)")

Output:

clearString: clearData0123456
clearData: <636c6561 72446174 61303132 33343536>

hashSHA256: <aabc766b 6b357564 e41f4f91 2d494bcc bfa16924 b574abbd ba9e3e9d a0c8920a>
hashMD5: <4df665f7 b94aea69 695b0e7b baf9e9d6>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Swift 中使用 SHA512 的哈希字符串 的相关文章

随机推荐

  • 如何在 Spring Boot 项目的调试/运行时在 IntelliJ“out”目录中生成 build-info.properties?

    在我的 build gradle 中 我添加了 spring 构建信息 springBoot mainClass springBootMainClass buildInfo additionalProperties name appName
  • 自定义 HashMap 实现

    这个问题是在一次采访中问我的 我认为获得最佳解决方案的唯一方法是 SOF 所以问题是 如何在java中实现自定义HashMap 假设没有称为HashMap的数据结构 我能想到的唯一答案是实现关联数组 但话又说回来 Java 没有关联数组 对
  • 关闭 Eclipse / Aptana 中的工具提示

    我不知道是否有人注意到 Eclipse 有这个烦人的功能 它需要在悬停任何东西时显示无用的工具提示 我想知道是否有人知道一种方法可以完全消除 Eclipse Aptana 中的所有工具提示行为 Thanks 我在 Window gt Pre
  • 无法链接到 libgfortran.a [重复]

    这个问题在这里已经有答案了 我的系统和文件上安装了 gfortranlibgfortran a可以在以下位置找到 usr lib gcc x86 64 linux gnu 4 6 Using nm我确定该功能 gfortran compar
  • 从两个列表中删除一个元素

    我有 list a 和 list b 这两个列表都有订单中的项目 每次我在 list b 中遇到 0 时 我想从 list a AND list b 中删除与该索引关联的条目 我不知道该怎么做 Before modification lis
  • 长型64位linux

    非常简单的问题 伙计们 但也许我只是忘记了一些事情 在64位linux中 long是8字节正确吗 如果是这种情况 并且我想设置第 64 位 我可以执行以下操作 unsigned long num 1 lt lt 63 然而 每当我编译这个时
  • Eclipse ADT 捆绑包链接在哪里? [复制]

    这个问题在这里已经有答案了 在 Android 开发的官方网站上 我无法再看到 Eclipse ADT 捆绑包的链接 我无法切换到 Android Studio 因为我的框架当前是基于 Ant 的 而不是Gradle https en wi
  • 如何在 Flutter 中创建带圆角的模态底板?

    显示模态底部表不提供任何造型或装饰 我想创建类似 Google Tasks 底页的内容 更新于 2019 08 05 您现在可以使用默认值来完成此操作showModalBottomSheet现在支持添加的方法ShapeBorder并且bac
  • Jooq LocalDateTime 字段使用系统时区而不是会话时区

    我正在使用 jooq v3 11 9 访问以 UTC 时间运行的 MySQL 数据库 我使用生成的实体并使用 JSR 310 时间类型 我在配置中使用的选项
  • Spring 和 XSLT,字符编码

    我对 HTML 视图的正确字符集编码部分有疑问 JSP 文件中的 XSL 文件生成 html 数据库中的值编码正确 但表的静态标头包含错误的字符 例如 有一些标题名称为 伊米斯 纳兹维斯科 哈斯洛 普莱奇 但它会生成 Imi Nazwisk
  • 如何使用 Xaml 中的 SortDescriptions 对 TreeView 项目进行排序?

    我有一个清单Layers绑定到一个TreeView其中每个实例都有一个列表Effects 我通过 HierarchicalDataTemplate 向它们展示 该模板效果很好 但我正在尝试使用它们对它们进行排序SortDescription
  • 使用 JavaScript/JQuery 打开最大化新窗口的最快方法?

    什么是fastest打开新窗口的方法 最大化 使用与大多数浏览器兼容的 JavaScript 和 或 JQuery
  • 使用数据属性滚动到元素

    我试图弄清楚如何使用数据属性让元素滚动到与 ID 匹配的特定元素 而不是使用锚标记 这就是我正在做的事情 一旦用户单击按钮 它将显示内容并滚动到与数据属性匹配的特定元素 我似乎无法让它滚动 div class container div c
  • 在运行时动态组合 Boost.Spirit.Qi 规则(任意数量的替代方案)

    我想知道 Boost Spirit Qi 中是否有一种方法可以在运行时动态组合任意数量的规则 Boost Spirit 的内部工作原理对我来说仍然有点神秘 但由于规则是作为对象实现的 所以它似乎是可行的 我的动机是使我的语法的某些部分易于扩
  • 通过 PHP 启动服务器端打印作业

    这很可能不是一件容易的事 但情况如下 我编写了一个 C 命令行应用程序 其中 使用 ITextSharp 创建 PDF 将其写入磁盘 uses Acrord32 exe 这是 Acrobat Reader 通过System Diagnost
  • 将bootloader和内核制作成iso? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 如何创建将内核加载到 iso 的简单引导加载程序 已经过去 5 天了 我在 google 中搜索并进行
  • Java - Swing - JTable - 设置所选行的颜色,但不设置单元格的颜色

    我试图让我的表格在您单击单元格时选择整行 可以通过关闭列选择来完成 但是 我不希望您单击的特定单元格周围的超厚边框突出显示 我希望这很容易 但显然它涉及渲染器 所以我做了很多研究 我能得到的最接近的是 JTable contactTable
  • SML:为什么函数总是采用一个参数使语言变得灵活

    我 从一本 SML 书中 了解到 SML 中的函数总是只接受一个参数 一个元组 接受多个参数的函数只是一个接受一个元组作为参数的函数 通过函数绑定中的元组绑定来实现 我明白这一点 但在这之后 书上说了一些我不明白的话 this point
  • Python - 使用 BeautifulSoup 抓取 ESPN 表

    我正在尝试使用 BeautifulSoup 来抓取 季节统计 表页 有什么办法可以将整个表变成一个汤对象吗 目前我的代码是这样的 seasonStats soup find table id statsTable categoryList
  • Swift 中使用 SHA512 的哈希字符串

    有人知道如何在 swift 中重现 PHP 哈希方法 hash SHA512 value true 吗 我尝试将 CommonCrypto C 库与以下代码一起使用 extension String func digest length I