19 votes

Comment convertir une chaîne hexadécimale en un tableau d'octets UInt8 en Swift ?

J'ai le code suivant :

var encryptedByteArray: Array<UInt8>?
do {
    let aes = try AES(key: "passwordpassword", iv: "drowssapdrowssap")
    encryptedByteArray = try aes.encrypt(Array("ThisIsAnExample".utf8))
} catch {
    fatalError("Failed to initiate aes!")
}

print(encryptedByteArray!) // Prints [224, 105, 99, 73, 119, 70, 6, 241, 181, 96, 47, 250, 108, 45, 149, 63]

let hexString = encryptedByteArray?.toHexString()

print(hexString!) // Prints e0696349774606f1b5602ffa6c2d953f

Comment puis-je convertir hexString dans le même tableau de UInt8 octets ?

La raison de ma question est que je veux communiquer avec un serveur par le biais d'une chaîne hexadécimale cryptée et j'ai besoin de la reconvertir en un tableau d'adresses. UInt8 octets pour décoder la chaîne de caractères dans sa forme originale.

42voto

Leo Dabus Points 122890

Vous pouvez reconvertir votre chaîne hexa en tableau de UInt8 en itérant tous les deux caractères hexa et initialiser un UInt8 à partir de celui-ci en utilisant l'initialisateur UInt8 radix 16 :

extension StringProtocol {
    var hexaToBytes: [UInt8] {
        let hexa = Array(self)
        return stride(from: 0, to: count, by: 2).compactMap { UInt8(String(hexa[$0...$0.advanced(by: 1)]), radix: 16) }
    }
}

ou

extension Collection where Element == Character {
    var hexaToBytes: [UInt8] {
        var last = first
        return dropFirst().compactMap {
            guard let char = last else {
                last = $0
                return nil
            }
            defer { last = nil }
            return UInt8(String([char,$0]), radix: 16)
        }
    }
}

Swift 5 ou plus

Nous pouvons utiliser la nouvelle propriété Character hexDigitValue.

extension Collection where Element == Character {
    var hexaToBytes: [UInt8] {
        var last = first
        return dropFirst().compactMap {
            guard
                let lastHexDigitValue = last?.hexDigitValue,
                let hexDigitValue = $0.hexDigitValue else {
                last = $0
                return nil
            }
            defer { last = nil }
            return UInt8(lastHexDigitValue * 16 + hexDigitValue)
        }
    }
}

Terrain de jeux :

let hexa = "e0696349774606f1b5602ffa6c2d953f"

let bytes = hexa.hexaToBytes   // [224, 105, 99, 73, 119, 70, 6, 241, 181, 96, 47, 250, 108, 45, 149, 63]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X