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

问题描述 投票:0回答:1

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

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

我的快速解决方案:

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

但是有两种情况:

  • 如果第一个字节为正:java和swift都给我相同的结果
  • 如果第一个字节为负:java给我一个负数(如预期),但是swift给我一个正数...

示例:

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", $0) }).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", $0) }).joined())
// 70aca7788576cef98d9f8129b934fc69fbb07356

Swift Playground screenshot

快速实施有什么问题?

java swift hex biginteger bigint
1个回答
0
投票

我终于写了我自己的解决方案,迭代字节并组合字符串。经过不同阵列测试,可用于正负十六进制。

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: $0) }))
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: $0) }))
print(bytes2.toSignedHexString() == "70aca7788576cef98d9f8129b934fc69fbb07356")
// true
© www.soinside.com 2019 - 2024. All rights reserved.