Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Hex String to NSData in Swift

I got the code to convert String to HEX-String in Objective-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; } 

I want the same in Swift. Can anybody translate this code in Swift, or is there any easy way to do this in Swift?

like image 785
Qadir Hussain Avatar asked Oct 22 '14 06:10

Qadir Hussain


People also ask

What is swift 4-from data to Hex string?

12 Swift 4 - From Data to Hex String Based upon Martin R's solutionbut even a tiny bit faster. extension Data { /// A hexadecimal string representation of the bytes.

Can NSData be represented in hexadecimal?

NSData can be represented as hexadecimal string, similar to what it outputs in its description method. extension NSData { func hexString () -> String { return UnsafeBufferPointer<UInt8> (start: UnsafePointer<UInt8> (bytes), count: length) .reduce ("") { $0 + String (format: "%02x", $1) } } }

How to convert string to and from data/NSData?

To convert String to and from Data / NSData we need to encode this string with a specific encoding. The most famous one is UTF-8 which is an 8-bit representation of Unicode characters, suitable for transmission or storage by ASCII-based systems. Here is a list of all available String Encodings

What is UTF-16 in Swift?

@MiladFaridnia: UTF-16 is what Swift strings use internally. The above function returns a string containing only digits 0...9 and the letters A...F, so that should not be a problem. – Martin R


1 Answers

This is my hex string to Data routine:

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: 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     }      } 

And for the sake of completeness, this is my Data to hex string routine:

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

Note, as shown in the above, I generally only convert between hexadecimal representations and NSData instances (because if the information could have been represented as a string you probably wouldn't have created a hexadecimal representation in the first place). But your original question wanted to convert between hexadecimal representations and String objects, and that might look like so:

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     }      } 

You could then use the above like so:

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

Or,

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

For permutations of the above for earlier Swift versions, see the revision history of this question.

like image 89
Rob Avatar answered Oct 03 '22 01:10

Rob