当第一个字节为负时,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())
但是有两种情况:
- 如果第一个字节是正数: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", [=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
我正在尝试将 [UInt8] 转换为十六进制字符串,就像可以在 java 中完成的那样:
byte[] bytes = {...};
System.out.println(new BigInteger(bytes).toString(16));
我的swift解决方案:
let bytes: [Int8] = [...]
print(bytes.map({ String(format: "%02hhx", [=11=]) }).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", [=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