Как преобразовать данные в шестнадцатеричную строку в swift

Я хочу шестнадцатеричное представление значения Data в Swift.

В конце концов я бы хотел использовать его так:

let data = Data(base64Encoded: "aGVsbG8gd29ybGQ=")! print(data.hexString) 

Альтернативная реализация (взятая из « Как склеить строку в sha1 с помощью Swift?» , С дополнительной опцией для ввода верхнего регистра) будет

 extension Data { struct HexEncodingOptions: OptionSet { let rawValue: Int static let upperCase = HexEncodingOptions(rawValue: 1 << 0) } func hexEncodedString(options: HexEncodingOptions = []) -> String { let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx" return map { String(format: format, $0) }.joined() } } 

Я выбрал hexEncodedString(options:) в стиле существующего метода base64EncodedString(options:) .

Data соответствуют протоколу Collection , поэтому можно использовать map() для сопоставления каждого байта с соответствующей шестнадцатеричной строкой. Формат %02x печатает аргумент в базе 16, заполняя до двух цифр нулевым при необходимости. Модификатор hh вызывает аргумент (который передается как целое число в стеке) для обработки как количество байтов. Здесь можно опустить модификатор, потому что $0 – это беззнаковое число ( UInt8 ), и никакого расширения знака не произойдет, но это не вредит ему.

Результат затем соединяется с одной строкой.

Пример:

 let data = Data(bytes: [0, 1, 127, 128, 255]) print(data.hexEncodedString()) // 00017f80ff print(data.hexEncodedString(options: .upperCase)) // 00017F80FF 

Следующая реализация выполняется быстрее примерно в 120 раз (проверено с 1000 случайными байтами). Он похож на решение RenniePet и решение Nick Moore , но на основе кодовых блоков UTF-16, которые являются строками Swift (в настоящее время) в качестве внутреннего хранилища.

 extension Data { struct HexEncodingOptions: OptionSet { let rawValue: Int static let upperCase = HexEncodingOptions(rawValue: 1 << 0) } func hexEncodedString(options: HexEncodingOptions = []) -> String { let hexDigits = Array((options.contains(.upperCase) ? "0123456789ABCDEF" : "0123456789abcdef").utf16) var chars: [unichar] = [] chars.reserveCapacity(2 * count) for byte in self { chars.append(hexDigits[Int(byte / 16)]) chars.append(hexDigits[Int(byte % 16)]) } return String(utf16CodeUnits: chars, count: chars.count) } } 

Моя версия. Это не так элегантно, но это примерно в 10 раз быстрее, чем принятый ответ Мартина Р.

 extension Data { private static let hexAlphabet = "0123456789abcdef".unicodeScalars.map { $0 } public func hexEncodedString() -> String { return String(self.reduce(into: "".unicodeScalars, { (result, value) in result.append(Data.hexAlphabet[Int(value/16)]) result.append(Data.hexAlphabet[Int(value%16)]) })) } } 

Этот код расширяет тип Data с помощью вычисленного свойства. Он выполняет итерацию через байты данных и объединяет шестнадцатеричное представление байта с результатом:

 extension Data { var hexDescription: String { return reduce("") {$0 + String(format: "%02x", $1)} } } 

Это не отвечает на вопрос OP, поскольку он работает с массивом Swift byte, а не с объектом Data. И это намного больше, чем другие ответы. Но он должен быть более эффективным, поскольку он избегает использования String (format:).

Во всяком случае, в надежде кто-то находит это полезным …

 public class StringMisc { // MARK: - Constants // This is used by the byteArrayToHexString() method private static let CHexLookup : [Character] = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ] // Mark: - Public methods /// Method to convert a byte array into a string containing hex characters, without any /// additional formatting. public static func byteArrayToHexString(_ byteArray : [UInt8]) -> String { var stringToReturn = "" for oneByte in byteArray { let asInt = Int(oneByte) stringToReturn.append(StringMisc.CHexLookup[asInt >> 4]) stringToReturn.append(StringMisc.CHexLookup[asInt & 0x0f]) } return stringToReturn } } 

Прецедент:

  // Test the byteArrayToHexString() method let byteArray : [UInt8] = [ 0x25, 0x99, 0xf3 ] assert(StringMisc.byteArrayToHexString(byteArray) == "2599F3") 
  • Быстрая бета-версия 6 - Ошибка сообщения об ошибке компоновщика
  • @selector () в Swift?
  • Операторы «++» и «-» устарели Xcode 7.3
  • структура против classа в быстром языке
  • Когда мне нужно быстро получить доступ к свойствам с помощью self?
  • Загрузите UIView из nib в Swift
  • Swift - Пользовательский сеттер на свойстве
  • Что означает «@UIApplicationMain»?
  • Получите верхний ViewController в iOS Swift
  • Строковое значение для режима UnsafePointer
  • Как отправить запрос POST и GET?
  • Давайте будем гением компьютера.