如何快速将数据转换为十六进制字符串 [英] How to convert Data to hex string in swift

查看:126
本文介绍了如何快速将数据转换为十六进制字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要Swift中Data值的十六进制表示形式.

I want the hexadecimal representation of a Data value in Swift.

最终我想像这样使用它:

Eventually I'd want to use it like this:

let data = Data(base64Encoded: "aGVsbG8gd29ybGQ=")!
print(data.hexString)

推荐答案

一种替代实现(取自

An alternative implementation (taken from How to crypt string to sha1 with Swift?, with an additional option for uppercase output) would be

extension Data {
    struct HexEncodingOptions: OptionSet {
        let rawValue: Int
        static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
    }

    func hexEncodedString(options: HexEncodingOptions = []) -> String {
        let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
        return map { String(format: format, $0) }.joined()
    }
}

我以现有方法base64EncodedString(options:)的样式选择了hexEncodedString(options:)方法.

I chose a hexEncodedString(options:) method in the style of the existing method base64EncodedString(options:).

Data符合Collection协议,因此可以使用 map()将每个字节映射到相应的十六进制字符串. %02x格式以16为基数打印参数,最多两位数 如有必要,前导零. hh修饰符引起参数 (作为整数在堆栈上传递),将被视为一个字节 数量.因为$0 unsigned ,所以这里可以省略修饰符 数字(UInt8)并且不会出现符号扩展名,但不会造成任何危害 进来.

Data conforms to the Collection protocol, therefore one can use map() to map each byte to the corresponding hex string. The %02x format prints the argument in base 16, filled up to two digits with a leading zero if necessary. The hh modifier causes the argument (which is passed as an integer on the stack) to be treated as a one byte quantity. One could omit the modifier here because $0 is an unsigned number (UInt8) and no sign-extension will occur, but it does no harm leaving it in.

然后将结果连接到单个字符串.

The result is then joined to a single string.

示例:

let data = Data(bytes: [0, 1, 127, 128, 255])
print(data.hexEncodedString()) // 00017f80ff
print(data.hexEncodedString(options: .upperCase)) // 00017F80FF


以下实现的速度提高了约120倍 (使用1000个随机字节进行了测试).它类似于 RenniePet的解决方案尼克·摩尔的解决方案,但是基于UTF-16代码单元,这就是Swift 字符串(当前)用作内部存储.


The following implementation is faster by a factor about 120 (tested with 1000 random bytes). It is similar to RenniePet's solution and Nick Moore's solution, but based on UTF-16 code units, which is what Swift strings (currently) use as internal storage.

extension Data {
    struct HexEncodingOptions: OptionSet {
        let rawValue: Int
        static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
    }

    func hexEncodedString(options: HexEncodingOptions = []) -> String {
        let hexDigits = Array((options.contains(.upperCase) ? "0123456789ABCDEF" : "0123456789abcdef").utf16)
        var chars: [unichar] = []
        chars.reserveCapacity(2 * count)
        for byte in self {
            chars.append(hexDigits[Int(byte / 16)])
            chars.append(hexDigits[Int(byte % 16)])
        }
        return String(utf16CodeUnits: chars, count: chars.count)
    }
}

这篇关于如何快速将数据转换为十六进制字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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