Python a deux méthodes de bibliothèque très utiles (binascii.a2b_hex (keyStr) et binascii.hexlify (keyBytes)) avec lesquelles j'ai lutté dans Swift. Y at-il quelque chose facilement disponible dans Swift. Sinon, comment l'appliquer? Compte tenu de toutes les limites et d'autres contrôles (comme la clé de longueur égale) sont faits.conversion de chaîne hexadécimal/binaire dans Swift
Répondre
Pas vraiment familier avec Python et les contrôles qu'il effectue lors de convertir les chiffres, mais vous pouvez étendre la fonction ci-dessous:
func convert(_ str: String, fromRadix r1: Int, toRadix r2: Int) -> String? {
if let num = Int(str, radix: r1) {
return String(num, radix: r2)
} else {
return nil
}
}
convert("11111111", fromRadix: 2, toRadix: 16)
convert("ff", fromRadix: 16, toRadix: 2)
Swift 2
extension NSData {
class func dataFromHexString(hex: String) -> NSData? {
let regex = try! NSRegularExpression(pattern: "^[0-9a-zA-Z]*$", options: .CaseInsensitive)
let validate = regex.firstMatchInString(hex, options: NSMatchingOptions.init(rawValue: 0), range: NSRange(location: 0, length: hex.characters.count))
if validate == nil || hex.characters.count % 2 != 0 {
return nil
}
let data = NSMutableData()
for i in 0..<hex.characters.count/2 {
let hexStr = hex.substring(i * 2, length: 2)
var ch: UInt32 = 0
NSScanner(string: hexStr).scanHexInt(&ch)
data.appendBytes(&ch, length: 1)
}
return data
}
}
let a = 0xabcd1234
print(String(format: "%x", a)) // Hex to String
NSData.dataFromHexString("abcd1234") // String to hex
Data
de Swift 3 n'a pas " "intégré" méthode pour imprimer son contenu comme une chaîne hexadécimale, ou pour créer une valeur Data
à partir d'une chaîne hexadécimale.
Des méthodes de "données à chaîne hexagonale" peuvent être trouvées par ex. au How to convert Data to hex string in swift ou How to print the content of a variable type Data using swift? ou converting string to data in swift 3.0. Voici une mise en œuvre du premier lien:
extension Data {
func hexEncodedString() -> String {
return map { String(format: "%02hhx", $0) }.joined()
}
}
Voici une implémentation possible de la « chaîne hexadécimale aux données » inverse conversion (extrait de Hex String to Bytes (NSData) sur la révision du Code, traduit à Swift 3 et amélioré) comme failable inititializer:
extension Data {
init?(fromHexEncodedString string: String) {
// Convert 0 ... 9, a ... f, A ...F to their decimal value,
// return nil for all other input characters
func decodeNibble(u: UInt16) -> UInt8? {
switch(u) {
case 0x30 ... 0x39:
return UInt8(u - 0x30)
case 0x41 ... 0x46:
return UInt8(u - 0x41 + 10)
case 0x61 ... 0x66:
return UInt8(u - 0x61 + 10)
default:
return nil
}
}
self.init(capacity: string.utf16.count/2)
var even = true
var byte: UInt8 = 0
for c in string.utf16 {
guard let val = decodeNibble(u: c) else { return nil }
if even {
byte = val << 4
} else {
byte += val
self.append(byte)
}
even = !even
}
guard even else { return nil }
}
}
Exemple:
// Hex string to Data:
if let data = Data(fromHexEncodedString: "0002468A13579BFF") {
let idata = Data(data.map { 255 - $0 })
// Data to hex string:
print(idata.hexEncodedString()) // fffdb975eca86400
} else {
print("invalid hex string")
}
Cela mérite 1 000 000 de points. Super propre et utile. Merci d'avoir partagé! – dustinrwh
@anonymous ces réponses ne sont pas applicables sur les grands nombres. Je parle de nombres hexadécimaux à 32 chiffres. Le moyen efficace serait d'avoir une chaîne si grande et transformer l'entrée en un tableau d'octets. Swift stdlib n'a pas BigInteger et ce genre de conversions dans stdlib dès maintenant. – johndoe