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?
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.
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) } } }
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
@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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With