In swift 2 what is the best way to go about turning strings of hex characters into their ascii equivalent.
let str1 = "0x4d 0x4c 0x4e 0x63"
let str2 = "4d 4c 4e 63"
let str3 = "4d4c4e63"
let str4 = "4d4d 4e63"
let str5 = "4d,4c,4e,63"
we would like to run a function (or string extension) that spits out: 'MLNc' which is the ascii equivalent of the hex strings
strtoul
func hexStringtoAscii(hexString : String) -> String {
let hexArray = split(hexString.characters) { $0 == " "}.map(String.init)
let numArray = hexArray.map{ strtoul($0, nil, 16) }.map{Character(UnicodeScalar(UInt32($0)))}
return String(numArray)
}
Is this partial implementation on the correct path? And if so, how is the best way to handle the chunking
Using regular expression matching is one possible method to extract the
"hex numbers" from the string.
What you are looking for is an optional "0x", followed by exactly
2 hex digits. The corresponding regex pattern is "(0x)?([0-9a-f]{2})"
.
Then you can convert each match to a Character
and finally concatenate
the characters to a String
, quite similar to your "partial implementation". Instead of strtoul()
you can use the UInt32
initializer
init?(_ text: String, radix: Int = default)
which is new in Swift 2.
The pattern has two "capture groups" (encloses in parentheses),
the first one matches the optional "0x", and the second one matches
the two hex digits, the corresponding range can be retrieved with
rangeAtIndex(2)
.
This leads to the following implementation which can handle all your sample strings:
func hexStringtoAscii(hexString : String) -> String {
let pattern = "(0x)?([0-9a-f]{2})"
let regex = try! NSRegularExpression(pattern: pattern, options: .CaseInsensitive)
let nsString = hexString as NSString
let matches = regex.matchesInString(hexString, options: [], range: NSMakeRange(0, nsString.length))
let characters = matches.map {
Character(UnicodeScalar(UInt32(nsString.substringWithRange($0.rangeAtIndex(2)), radix: 16)!))
}
return String(characters)
}
(See Swift extract regex matches for an explanation for the conversion to NSString
.)
Note that this function is quite lenient, it just searches for 2-digit hex strings and ignores all other characters, so this would be accepted as well:
let str6 = "4d+-4c*/4e😈🇩🇪0x63"
Update for Swift 5.1:
func hexStringtoAscii(_ hexString : String) -> String {
let pattern = "(0x)?([0-9a-f]{2})"
let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let nsString = hexString as NSString
let matches = regex.matches(in: hexString, options: [], range: NSMakeRange(0, nsString.length))
let characters = matches.map {
Character(UnicodeScalar(UInt32(nsString.substring(with: $0.range(at: 2)), radix: 16)!)!)
}
return String(characters)
}
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