web-dev-qa-db-fra.com

Swift fonctions natives pour avoir des nombres sous forme de chaînes hexadécimales

Existe-t-il une manière native Swift pour tout nombre (au moins entier) d'obtenir sa représentation hexadécimale dans une chaîne? Et l'inverse. Elle ne doit pas utiliser Foundation. Par exemple, la classe String a une fonction

func toInt() -> Int?

qui convertit une chaîne représentant un entier en sa valeur Int. Je cherche quelque chose de similaire, en utilisant les chaînes hexadécimales. Je sais que cela est facilement implémentable, mais si Swift l'a déjà là, ce serait mieux. Sinon, si vous avez déjà fait une extension de String et Int pour atteindre les objectifs suivants:

let anHex = "0xA0"
if let anInt = anHex.toInt() {
   println(anInt)               // prints 128
   println(anInt.toHexString()) // prints "0xA0"
}

Je sais que ce n'est pas sorcier, mais au cas où je vous en prie, partagez-le.

PS: Ceci est similaire à cette question , la différence est qu'il était très lié au framework Foundation, alors que je ne l'utilise pas dans mon code (ni que j'importe quoi d'autre) et pour l'instant je Je voudrais le conserver de cette manière, également à des fins d'apprentissage.

40
Michele Dall'Agata

Depuis Swift 2, tous les types entiers ont un constructeur

init?(_ text: String, radix: Int = default)

de sorte que les conversions d'entier en chaîne hexadécimale et de chaîne hexadécimale en entier puissent être effectuées avec des méthodes intégrées. Exemple:

let num = 1000
let str = String(num, radix: 16)
print(str) // "3e8"

if let num2 = Int(str, radix: 16) {
    print(num2) // 1000
}

(Ancienne réponse pour Swift 1:) La conversion d'un entier en une chaîne hexadécimale peut être effectuée avec

let hex = String(num, radix: 16)

(voir par exemple Comment convertir un nombre décimal en binaire dans Swift? ). Cela ne nécessite l'importation d'aucun Framework et fonctionne avec n'importe quelle base entre 2 et 36.

La conversion d'une chaîne hexadécimale en un entier peut être effectuée avec la fonction de bibliothèque BSD strtoul() (comparer Comment convertir un binaire en décimal dans Swift? ) si vous êtes prêt à import Darwin.

Sinon, il n'y a (pour autant que je sache) pas de méthode intégrée Swift. Voici une extension qui convertit une chaîne en nombre selon une base donnée:

extension UInt {
    init?(_ string: String, radix: UInt) {
        let digits = "0123456789abcdefghijklmnopqrstuvwxyz"
        var result = UInt(0)
        for digit in string.lowercaseString {
            if let range = digits.rangeOfString(String(digit)) {
                let val = UInt(distance(digits.startIndex, range.startIndex))
                if val >= radix {
                    return nil
                }
                result = result * radix + val
            } else {
                return nil
            }
        }
        self = result
    }
}

Exemple:

let hexString = "A0"
if let num = UInt(hexString, radix: 16) {
    println(num)
} else {
    println("invalid input")
}
76
Martin R

mise à jour: Xcode 7.2 • Swift 2.1.1

extension String {
    var drop0xPrefix:          String { return hasPrefix("0x") ? String(characters.dropFirst(2)) : self }
    var drop0bPrefix:          String { return hasPrefix("0b") ? String(characters.dropFirst(2)) : self }
    var hexaToDecimal:            Int { return Int(drop0xPrefix, radix: 16) ?? 0 }
    var hexaToBinaryString:    String { return String(hexaToDecimal, radix: 2) }
    var decimalToHexaString:   String { return String(Int(self) ?? 0, radix: 16) }
    var decimalToBinaryString: String { return String(Int(self) ?? 0, radix: 2) }
    var binaryToDecimal:          Int { return Int(drop0bPrefix, radix: 2) ?? 0 }
    var binaryToHexaString:    String { return String(binaryToDecimal, radix: 16) }
}

extension Int {
    var toBinaryString: String { return String(self, radix: 2) }
    var toHexaString:   String { return String(self, radix: 16) }
}

Essai:

print("7fffffffffffffff".hexaToDecimal)      // "9223372036854775807" decimal integer
print("0x7fffffffffffffff".hexaToDecimal)    // "9223372036854775807" decimal integer
print("7fffffffffffffff".hexaToBinaryString) // "111111111111111111111111111111111111111111111111111111111111111" binary (String)
print("0x7fffffffffffffff".hexaToBinaryString) // "111111111111111111111111111111111111111111111111111111111111111"

print("255".decimalToHexaString)   // "ff"       hexa (String)
print("255".decimalToBinaryString) // "11111111" binary (String)
0b11111111

print("11111111".binaryToHexaString)      // "ff"  hexa (String)
print("0b11111111".binaryToHexaString)    // "ff"  hexa (String)
print("11111111".binaryToDecimal)         // 255 decimal (Int)
print("0b11111111".binaryToDecimal)       // 255 decimal (Int)

print(255.toBinaryString) // "11111111" binary (String)
print(255.toHexaString)   // "ff"       hexadecimal (String)
16
Leo Dabus

Swift:

String à UInt:

let str = "fcd7d7"
let number = UInt(str, radix: 16)!
print(number)

résultat: 16570327

UInt en hex String:

let number = UInt(exactly: 16570327)!
let str = String(number, radix: 16, uppercase: false)
print(str)

résultat: fcd7d7

16
Ali Momen Sani

Pour Float, Si vous souhaitez que le point flottant IEEE754 soit HEX

extension Float {
 func floatToHex()->String {
    return String(self.bitPattern, radix: 16, uppercase: true)
 }
}
let f:Float = 3.685746e+19
let hex = f.floatToHex()

print("\(hex)")//5FFFC000

Ou Visa-versa

extension String {

 func hexToFloat() -> Float {
    var toInt = Int32(truncatingBitPattern: strtol(self, nil, 16))
    var toInt = Int32(_truncatingBits: strtoul(self, nil, 16)) //For Swift 5
    var float:Float32!
    memcpy(&float, &toInt, MemoryLayout.size(ofValue: float))
    return float
 }
}
2
Kraming