2016-10-27 2 views
2

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

+0

@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

Répondre

0

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) 
0

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 
8

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") 
} 
+1

Cela mérite 1 000 000 de points. Super propre et utile. Merci d'avoir partagé! – dustinrwh