programar programación programacion online objective lenguaje entre diferencias ios objective-c swift

ios - programación - swift to objective c online



Convertir cadena hexadecimal a NSData en Swift (6)

Aquí hay una solución simple que me decidí:

extension NSData { public convenience init(hexString: String) { var index = hexString.startIndex var bytes: [UInt8] = [] repeat { bytes.append(hexString[index...index.advancedBy(1)].withCString { return UInt8(strtoul($0, nil, 16)) }) index = index.advancedBy(2) } while index.distanceTo(hexString.endIndex) != 0 self.init(bytes: &bytes, length: bytes.count) } }

Uso:

let data = NSData(hexString: "b8dfb080bc33fb564249e34252bf143d88fc018f")

Salida:

print(data) >>> <b8dfb080 bc33fb56 4249e342 52bf143d 88fc018f>

Actualización 29/06/2016

Actualicé el inicializador para manejar datos mal formados (es decir, caracteres no válidos o un número impar de caracteres).

public convenience init?(hexString: String, force: Bool) { let characterSet = NSCharacterSet(charactersInString: "0123456789abcdefABCDEF") for scalar in hexString.unicodeScalars { if characterSet.characterIsMember(UInt16(scalar.value)) { hexString.append(scalar) } else if !force { return nil } } if hexString.characters.count % 2 == 1 { if force { hexString = "0" + hexString } else { return nil } } var index = hexString.startIndex var bytes: [UInt8] = [] repeat { bytes.append(hexString[index...index.advancedBy(1)].withCString { return UInt8(strtoul($0, nil, 16)) }) index = index.advancedBy(2) } while index.distanceTo(hexString.endIndex) != 0 self.init(bytes: &bytes, length: bytes.count) }

Obtuve el código para convertir String en HEX-String en object-C.

- (NSString *) CreateDataWithHexString:(NSString*)inputString { NSUInteger inLength = [inputString length]; unichar *inCharacters = alloca(sizeof(unichar) * inLength); [inputString getCharacters:inCharacters range:NSMakeRange(0, inLength)]; UInt8 *outBytes = malloc(sizeof(UInt8) * ((inLength / 2) + 1)); NSInteger i, o = 0; UInt8 outByte = 0; for (i = 0; i < inLength; i++) { UInt8 c = inCharacters[i]; SInt8 value = -1; if (c >= ''0'' && c <= ''9'') value = (c - ''0''); else if (c >= ''A'' && c <= ''F'') value = 10 + (c - ''A''); else if (c >= ''a'' && c <= ''f'') value = 10 + (c - ''a''); if (value >= 0) { if (i % 2 == 1) { outBytes[o++] = (outByte << 4) | value; outByte = 0; } else { outByte = value; } } else { if (o != 0) break; } } NSData *a = [[NSData alloc] initWithBytesNoCopy:outBytes length:o freeWhenDone:YES]; NSString* newStr = [NSString stringWithUTF8String:[a bytes]]; return newStr; }

Quiero lo mismo en Swift. ¿Alguien puede traducir este código en Swift, o hay alguna manera fácil de hacerlo en Swift?


El código funcionó para mí en Swift 3.0.2 .

extension String { /// Expanded encoding /// /// - bytesHexLiteral: Hex string of bytes /// - base64: Base64 string enum ExpandedEncoding { /// Hex string of bytes case bytesHexLiteral /// Base64 string case base64 } /// Convert to `Data` with expanded encoding /// /// - Parameter encoding: Expanded encoding /// - Returns: data func data(using encoding: ExpandedEncoding) -> Data? { switch encoding { case .bytesHexLiteral: guard self.characters.count % 2 == 0 else { return nil } var data = Data() var byteLiteral = "" for (index, character) in self.characters.enumerated() { if index % 2 == 0 { byteLiteral = String(character) } else { byteLiteral.append(character) guard let byte = UInt8(byteLiteral, radix: 16) else { return nil } data.append(byte) } } return data case .base64: return Data(base64Encoded: self) } } }


Esta es mi cadena hexadecimal a la rutina de Data :

extension String { /// Create `Data` from hexadecimal string representation /// /// This creates a `Data` object from hex string. Note, if the string has any spaces or non-hex characters (e.g. starts with ''<'' and with a ''>''), those are ignored and only hex characters are processed. /// /// - returns: Data represented by this hexadecimal string. var hexadecimal: Data? { var data = Data(capacity: characters.count / 2) let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive) regex.enumerateMatches(in: self, range: NSRange(startIndex..., in: self)) { match, _, _ in let byteString = (self as NSString).substring(with: match!.range) let num = UInt8(byteString, radix: 16)! data.append(num) } guard data.count > 0 else { return nil } return data } }

Y en aras de la integridad, esta es la rutina de Mis Data a cadena de caracteres hex:

extension Data { /// Hexadecimal string representation of `Data` object. var hexadecimal: String { return map { String(format: "%02x", $0) } .joined() } }

Tenga en cuenta que, como se muestra en la NSData anterior, generalmente solo convierto entre representaciones hexadecimales e instancias de NSData (porque si la información pudiera haber sido representada como una cadena, probablemente no habría creado una representación hexadecimal en primer lugar). Pero su pregunta original quería convertir entre representaciones hexadecimales y objetos String , y eso podría verse así:

extension String { /// Create `String` representation of `Data` created from hexadecimal string representation /// /// This takes a hexadecimal representation and creates a String object from that. Note, if the string has any spaces, those are removed. Also if the string started with a `<` or ended with a `>`, those are removed, too. /// /// For example, /// /// String(hexadecimal: "<666f6f>") /// /// is /// /// Optional("foo") /// /// - returns: `String` represented by this hexadecimal string. init?(hexadecimal string: String, encoding: String.Encoding = .utf8) { guard let data = string.hexadecimal() else { return nil } self.init(data: data, encoding: encoding) } /// Create hexadecimal string representation of `String` object. /// /// For example, /// /// "foo".hexadecimalString() /// /// is /// /// Optional("666f6f") /// /// - parameter encoding: The `String.Encoding` that indicates how the string should be converted to `Data` before performing the hexadecimal conversion. /// /// - returns: `String` representation of this String object. func hexadecimalString(encoding: String.Encoding = .utf8) -> String? { return data(using: encoding)? .hexadecimal } }

A continuación, podría utilizar el anterior como tal:

let hexString = "68656c6c 6f2c2077 6f726c64" print(String(hexadecimal: hexString))

O,

let originalString = "hello, world" print(originalString.hexadecimalString())

Para conocer las permutaciones de las versiones anteriores de Swift, consulte el historial de revisiones de esta pregunta.


Implementación de Swift 4 :

extension Data { init?(hexString: String) { let len = hexString.count / 2 var data = Data(capacity: len) for i in 0..<len { let j = hexString.index(hexString.startIndex, offsetBy: i*2) let k = hexString.index(j, offsetBy: 2) let bytes = hexString[j..<k] if var num = UInt8(bytes, radix: 16) { data.append(&num, count: 1) } else { return nil } } self = data } }

Uso:

let data = Data(hexString: "0a1b3c4d")


Lo único que necesitas del código de Rob es esto:

extension NSData { func toHexString() -> String { var string = NSMutableString(capacity: length * 2) var byte: UInt8 = 0 for i in 0 ..< length { getBytes(&byte, range: NSMakeRange(i, 1)) string.appendFormat("%02x", byte) } return string as String } }

Entonces hazlo

yourdataobject.toHexString()

Para obtener los datos binarios como una cadena hexadecimal. Suponiendo que su objeto de datos es de tipo NSData.


convertir la cadena hexadecimal a datos y cadena:

Swift1

func dataWithHexString(hex: String) -> NSData { var hex = hex let data = NSMutableData() while(countElements(hex) > 0) { var c: String = hex.substringToIndex(advance(hex.startIndex, 2)) hex = hex.substringFromIndex(advance(hex.startIndex, 2)) var ch: UInt32 = 0 NSScanner(string: c).scanHexInt(&ch) data.appendBytes(&ch, length: 1) } return data }

utilizar:

let data = dataWithHexString("68656c6c6f2c20776f726c64") // <68656c6c 6f2c2077 6f726c64> if let string = NSString(data: data, encoding: 1) { print(string) // hello, world }

Swift2

func dataWithHexString(hex: String) -> NSData { var hex = hex let data = NSMutableData() while(hex.characters.count > 0) { let c: String = hex.substringToIndex(hex.startIndex.advancedBy(2)) hex = hex.substringFromIndex(hex.startIndex.advancedBy(2)) var ch: UInt32 = 0 NSScanner(string: c).scanHexInt(&ch) data.appendBytes(&ch, length: 1) } return data }

utilizar:

let data = dataWithHexString("68656c6c6f2c20776f726c64") // <68656c6c 6f2c2077 6f726c64> if let string = String(data: data, encoding: NSUTF8StringEncoding) { print(string) //"hello, world" }

Swift3

func dataWithHexString(hex: String) -> Data { var hex = hex var data = Data() while(hex.characters.count > 0) { let c: String = hex.substring(to: hex.index(hex.startIndex, offsetBy: 2)) hex = hex.substring(from: hex.index(hex.startIndex, offsetBy: 2)) var ch: UInt32 = 0 Scanner(string: c).scanHexInt32(&ch) var char = UInt8(ch) data.append(&char, count: 1) } return data }

utilizar:

let data = dataWithHexString(hex: "68656c6c6f2c20776f726c64") // <68656c6c 6f2c2077 6f726c64> let string = String(data: data, encoding: .utf8) // "hello, world"

Swift4

func dataWithHexString(hex: String) -> Data { var hex = hex var data = Data() while(hex.count > 0) { let subIndex = hex.index(hex.startIndex, offsetBy: 2) let c = String(hex[..<subIndex]) hex = String(hex[subIndex...]) var ch: UInt32 = 0 Scanner(string: c).scanHexInt32(&ch) var char = UInt8(ch) data.append(&char, count: 1) } return data }

utilizar:

let data = dataWithHexString(hex: "68656c6c6f2c20776f726c64") // <68656c6c 6f2c2077 6f726c64> let string = String(data: data, encoding: .utf8) // "hello, world"