如何在 Swift 中使用 SHA1 散列 NSString? [英] How to hash NSString with SHA1 in Swift?

查看:71
本文介绍了如何在 Swift 中使用 SHA1 散列 NSString?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在objective-c中它看起来像这样:

In objective-c it looks like this:

#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 做这样的事情,这可能吗?

I need something like this with Swift, is it possible?

请展示工作示例.

推荐答案

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

Your Objective-C code (using a NSString category) can be directly translated to Swift (using a String extension).

首先你必须创建一个桥接头"并添加

First you have to create a "bridging header" and add

#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 编码的字符串而不是十六进制编码的字符串,只需替换

To return a Base-64 encoded string instead of a hex encoded string, just replace

        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 编码的字符串而不是十六进制编码的字符串,只需替换

To return a Base-64 encoded string instead of a hex encoded string, just replace

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

        return Data(bytes: digest).base64EncodedString()

Swift 4 更新:

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

The bridging header file is no longer needed, one can import CommonCrypto instead:

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() 方法现在使用 UnsafeRawBufferPointer 调用闭包,并且 baseAddress 用于将初始地址传递给C函数:

The Data.withUnsafeBytes() method now calls the closure with an UnsafeRawBufferPointer to, and baseAddress is used to pass the initial address to the C function:

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()
    }
}

这篇关于如何在 Swift 中使用 SHA1 散列 NSString?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆