2017-01-05 3 views
3

Я хочу, чтобы преобразовать следующие шестигранной кодируются String в Swift 3:Преобразовать шестигранной закодированной строки в строку

dcb04a9e103a5cd8b53763051cef09bc66abe029fdebae5e1d417e2ffc2a07a4 

его equivalant String:

Ü°J:\ص7cï ¼f«à)ýë®^A~/ü*¤ 

Эти сайты делают работу очень хорошо:

http://codebeautify.org/hex-string-converter

http://string-functions.com/hex-string.aspx

Но я не могу сделать то же самое в Swift 3. После кода не делает работу тоже:

func convertHexStringToNormalString(hexString:String)->String!{ 
    if let data = hexString.data(using: .utf8){ 
     return String.init(data:data, encoding: .utf8) 
    }else{ return nil} 
} 
+1

See http://stackoverflow.com/a/40278391/1187415 для метода создания «данных» из строки с шестнадцатеричным кодированием. –

+0

Но ваши данные не выглядят как допустимая строка в любой известной кодировке ... –

+2

Преобразование, как было предложено Марин R, представлением шестнадцатеричных, которое является строкой, в его эквивалент в '(NS) Data'. И используйте 'NSASCIIStringEncoding', а не' NSUTF8StringEncoding'. Я получаю в Objective-C правильный результат 'Ü ° J: \ Øμ7cï \t ¼f« à) ýë®^A ~/ü * ¤' с ASCII, но null с UTF8. – Larme

ответ

2

Вы хотите использовать шестигранные закодированные данные в качестве ключа AES, но данные не являются допустимой последовательностью UTF-8. Вы могли интерпретировать его как строку в ISO Latin кодировке, но AES(key: String, ...) инициализатор преобразует строку обратно в его представлении UTF-8, то есть вы будете получать различные данные ключа от того, что вы начали с.

Поэтому вы не должны преобразовывать его в строку вообще. С помощью метода

extension Data { 
    init?(fromHexEncodedString string: String) 
} 

от hex/binary string conversion in Swift для преобразования гекса закодированной строки в Data, а затем передать, что как массив к AES(key: Array<UInt8>, ...) инициализатору:

let hexkey = "dcb04a9e103a5cd8b53763051cef09bc66abe029fdebae5e1d417e2ffc2a07a4" 
let key = Array(Data(fromHexEncodedString: hexkey)!) 

let encrypted = try AES(key: key, ....) 
+0

Спасибо, Мартин, ты много помог. Могу ли я пометить оба ответа как правильно? –

+1

@ChanchalRaj - Я действительно думаю, что вы должны принять этот ответ, потому что это доходит до сути вашего вопроса, а именно, что вы не должны создавать объект String вообще, а используйте это '[UInt8]' исполнение методов AES , – Rob

3

Ваш код не делает то, что вы думаете. Эта линия:

если позволяют данные = hexString.data (с помощью: .utf8) {

означает "закодировать эти символы в кодировке UTF-8." Это означает, что «01» не кодируется в 0x01 (1), он кодирует 0x30 0x31 («0» «1»). Там нигде нет «шестерки».

Эта линия:

return String.init(data:data, encoding: .utf8) 

просто принимает кодированные данные UTF-8, интерпретирует это как UTF-8, и возвращает его. Эти два метода являются симметричными, поэтому вы должны ожидать, что вся эта функция вернет все, что было передано.

Собрать комментарии Мартина и Ларма в одном месте. Это, по-видимому, кодируется на латинице-1. (Это очень неудобно способ кодирования этой информации, но если это то, что вы ищете, я думаю, что это кодировка.)

import Foundation 

extension Data { 

    // From http://stackoverflow.com/a/40278391: 
    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 } 
    } 
} 

let d = Data(fromHexEncodedString: "dcb04a9e103a5cd8b53763051cef09bc66abe029fdebae5e1d417e2ffc2a07a4")! 
let s = String(data: d, encoding: .isoLatin1) 
+0

Спасибо, Роб, за вход. Мне интересно, почему Swift печатает преобразованную строку как: 'Необязательно (" Ü ° J \ u {10}: \\ Øμ7c \ u {05} \ u {1C} ï \ t¼f «à) ýë®^\ u { 1D} A ~/ü * \ u {07} ¤ ")' вместо желаемого: 'Ü ° J: \ Øμ7cï ¼f« à) ýë®^A ~/ü * ¤' –

+2

@ChanchalRaj: Потому что вы не разверните опцию. * Необязательные * строки используют немного другой метод печати, который ускользает от управляющих символов. –

Смежные вопросы