当前位置: 首页 > 面试题库 >

如何在Swift中使用SHA1哈希NSString?

袁秦迟
2023-03-14
问题内容

在Objective-C中,它看起来像这样:

#include <sys/xattr.h>

@implementation NSString (reverse)

-(NSString*)sha1
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (int)data.length, digest);
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];
    return output;
}

@end

我需要Swift这样的东西,可以吗?

请显示工作示例。


问题答案:

您的Objective-C代码(使用NSString类别)可以直接转换为Swift(使用String扩展名)。

首先,您必须创建一个“桥接头”并添加

#import <CommonCrypto/CommonCrypto.h>

然后:

extension String {
    func sha1() -> String {
        let data = self.dataUsingEncoding(NSUTF8StringEncoding)!
        var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
        CC_SHA1(data.bytes, CC_LONG(data.length), &digest)
        let output = NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH))
        for byte in digest {
            output.appendFormat("%02x", byte)
        }
        return output as String
    }
}

println("Hello World".sha1())

这可以写得更短和更快速

extension String {
    func sha1() -> String {
        let data = self.dataUsingEncoding(NSUTF8StringEncoding)!
        var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
        CC_SHA1(data.bytes, CC_LONG(data.length), &digest)
        let hexBytes = map(digest) { String(format: "%02hhx", $0) }
        return "".join(hexBytes)
    }
}

Swift 2更新:

extension String {
    func sha1() -> String {
        let data = self.dataUsingEncoding(NSUTF8StringEncoding)!
        var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
        CC_SHA1(data.bytes, CC_LONG(data.length), &digest)
        let hexBytes = digest.map { String(format: "%02hhx", $0) }
        return hexBytes.joinWithSeparator("")
    }
}

要返回以Base-64编码的字符串而不是十六进制编码的字符串,只需替换

        let hexBytes = digest.map { String(format: "%02hhx", $0) }
        return hexBytes.joinWithSeparator("")

        return NSData(bytes: digest, length: digest.count).base64EncodedStringWithOptions([])

Swift 3更新:

extension String {
    func sha1() -> String {
        let data = self.data(using: String.Encoding.utf8)!
        var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
        data.withUnsafeBytes { 
            _ = CC_SHA1($0, CC_LONG(data.count), &digest)
        }
        let hexBytes = digest.map { String(format: "%02hhx", $0) }
        return hexBytes.joined()
    }
}

要返回以Base-64编码的字符串而不是十六进制编码的字符串,只需替换

        let hexBytes = digest.map { String(format: "%02hhx", $0) }
        return hexBytes.joined()

通过

        return Data(bytes: digest).base64EncodedString()

Swift 4更新:

不再需要桥接头文件,import CommonCrypto而可以:

import CommonCrypto

extension String {
    func sha1() -> String {
        let data = Data(self.utf8)
        var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
        data.withUnsafeBytes { 
            _ = CC_SHA1($0, CC_LONG(data.count), &digest)
        }
        let hexBytes = digest.map { String(format: "%02hhx", $0) }
        return hexBytes.joined()
    }
}

Swift 5更新:

Data.withUnsafeBytes()方法现在使用to
调用闭包UnsafeRawBufferPointer,并baseAddress用于将初始地址传递给C函数

import CommonCrypto

extension String {
    func sha1() -> String {
        let data = Data(self.utf8)
        var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
        data.withUnsafeBytes { 
            _ = CC_SHA1($0.baseAddress, CC_LONG(data.count), &digest)
        }
        let hexBytes = digest.map { String(format: "%02hhx", $0) }
        return hexBytes.joined()
    }
}


 类似资料:
  • 问题内容: 我想创建一个(用键签名)的哈希 如何使用Node.js Crypto创建该哈希? 问题答案: 加密文档:http : //nodejs.org/api/crypto.html

  • 问题内容: 我有一个简单的问题,当我想将SHA1哈希的结果存储在MySQL数据库中时发生: 我将散列结果存储在 VARCHAR 字段中多长时间? 问题答案: 我将使用可变长度的数据,但不使用固定长度的数据。由于SHA-1值 始终为 160位长,因此将仅在固定长度字段的长度上浪费一个额外的字节。 而且我也不会存储返回的值。因为每个字符只使用4位,因此需要160/4 = 40个字符。但是,如果每个字符

  • 使用md5和sha1对同一个变量进行散列,是否会使字符串更难解密并提高安全性? 将同一字符串的MD5和SHA1版本串联起来,然后最后用中的任何一个再次哈希,是否有帮助?

  • 问题内容: 我想将“ abc”之类的字符串转换为MD5哈希。我想在iOS和Swift中做到这一点。我尝试使用下面的解决方案 http://iosdeveloperzone.com/2014/10/03/using-commoncrypto-in- swift/ 更清楚地说,我想在Swift中实现类似于此PHP代码输出的输出: 输出:8b1a9953c4611296a827abf8c47804d7

  • 问题内容: 我有两个用于计算SHA1的小片段。 一个非常快,但似乎不正确,另一个非常慢,但正确。 我认为转换为问题。 快速版本: 慢版本: 转换方式: 我希望有另一种可能使其运行,因为我需要性能。 问题答案: 我使用了JNI加载的高性能c ++实现。 有关更多详细信息,请发表评论。 编辑: JNI的要求是Android NDK。对于Windows,还需要cygwin或类似的东西。 如果您决定使用c

  • 问题内容: 我正在使用此行为node.js生成sha1 id: 问题在于它每次都返回相同的id。 是否有可能每次都生成一个随机ID,因此我可以将其用作数据库文档ID? 问题答案: 在这里看看: 我将创建当前时间戳的哈希值+一个随机数,以确保哈希值唯一性: