当第一个字节为负时,Int8 数组到带符号的十六进制字符串不起作用

Int8 array to signed hex string doesn't work when first byte is negative

我正在尝试将 [UInt8] 转换为十六进制字符串,就像可以在 java 中完成的那样:

byte[] bytes = {...};
System.out.println(new BigInteger(bytes).toString(16));

我的swift解决方案:

let bytes: [Int8] = [...]
print(bytes.map({ String(format: "%02hhx", [=11=]) }).joined())

但是有两种情况:

示例:

byte[] bytes = {-100, -21, -46, 47, -99, 39, 67, 53, 62, -2, -23, 104, -15, 117, -9, 40, -31, 70, 4, 28};
System.out.println(new BigInteger(bytes).toString(16));
// -63142dd062d8bccac10116970e8a08d71eb9fbe4
let bytes: [Int8] = [-100, -21, -46, 47, -99, 39, 67, 53, 62, -2, -23, 104, -15, 117, -9, 40, -31, 70, 4, 28]
print(bytes.map({ String(format: "%02hhx", [=13=]) }).joined())
// 9cebd22f9d2743353efee968f175f728e146041c

但是

byte[] bytes = {112, -84, -89, 120, -123, 118, -50, -7, -115, -97, -127, 41, -71, 52, -4, 105, -5, -80, 115, 86};
System.out.println(new BigInteger(bytes).toString(16));
// 70aca7788576cef98d9f8129b934fc69fbb07356
let bytes: [Int8] = [112, -84, -89, 120, -123, 118, -50, -7, -115, -97, -127, 41, -71, 52, -4, 105, -5, -80, 115, 86]
print(bytes.map({ String(format: "%02hhx", [=15=]) }).joined())
// 70aca7788576cef98d9f8129b934fc69fbb07356

swift 实施有什么问题?

我终于写了自己的解决方案,迭代字节并组合字符串。使用不同的数组进行测试,并且适用于正十六进制和负十六进制。

extension Data {

    func toSignedHexString() -> String {
        // Create an empty string
        var result = ""
        var first: Int8 = 0

        // Iterate bytes
        var bytes = map { byte in
            // Convert to Int8
            return Int8(bitPattern: byte)
        }
        while !bytes.isEmpty {
            // Get and remove the first byte
            let byte = bytes.removeFirst()

            // Check if this byte is the first byte
            if result.isEmpty && first == 0 {
                // Save the first byte
                first = byte
            } else if result.isEmpty && first != 0 {
                // Convert two first bytes to hex
                result.append(String(Int32(first + 1) * 256 + Int32(byte) + (first < 0 ? 1 : 0), radix: 16, uppercase: false))
            } else {
                // Convert it to hex
                result.append(String(format: "%02hhx", first < 0 ? (Int32(bytes.isEmpty ? 256 : 255) - Int32(byte)) % 256 : byte))
            }
        }

        // Return the final result
        return result
    }

}

测试代码:

let bytes = Data([-100, -21, -46, 47, -99, 39, 67, 53, 62, -2, -23, 104, -15, 117, -9, 40, -31, 70, 4, 28].map({ UInt8(bitPattern: [=11=]) }))
print(bytes.toSignedHexString() == "-63142dd062d8bccac10116970e8a08d71eb9fbe4")
// true

let bytes2 = Data([112, -84, -89, 120, -123, 118, -50, -7, -115, -97, -127, 41, -71, 52, -4, 105, -5, -80, 115, 86].map({ UInt8(bitPattern: [=11=]) }))
print(bytes2.toSignedHexString() == "70aca7788576cef98d9f8129b934fc69fbb07356")
// true