how do i convert a hex string to its unicode ascii equivalent in swift?

2.6k Views Asked by At

i've been trying to convert a hexadecimal string im getting via serial to something i can use as an ascii string using swift.

for example, if this is the string: "<01736c65 65702061 6e642062 61747465 72206c65>"

i want to convert it to a string that says "sleep and batter le"

note: that we would have to remove the carrots at the front and end of the string.

ive been going at this for two days and there isnt an elegant or simple solution. any ideas would be really appreciated.

I got this far,

func hex2ascii (example: String) -> String {

let chars = Array(example)
let numbers = map (stride(from: 0, to: chars.count, by: 2)) {
    strtoul(String(chars[$0 ..< $0+2]), nil, 16)
}

var final = ""
var i = 0

while i < numbers.count {
    final.append(Character(UnicodeScalar(Int(numbers[i]))))
    i++
}
return final
}

for example, an input "<01736c65 65702061 6e642062 61747465 72206c65>" returns this`"6Æep aæBatte"Æ"'

obviously not right, how to do fix this?

4

There are 4 best solutions below

1
On BEST ANSWER

It seems you are not stripping off the angle braces and spaces between your hex digits.

The output you get "6Æep aæBatte"Æ"corresponds to this unicode entities (with spaces added):

%22 %36 %C6 %65 %70 %20 %61 %E6 %62 %61 %74 %74 %65 %22 %C6 %22

I don't know where the double quotes come from, but comparing it with the original hex string you can see that the spaces make you loose a digit, displacing the numbers.

<01736c65 65702061 6e642062 61747465 72206c65>

Note the chars %36, %c6 and %E6 produced by the character shift.

I used this page to encode and decode.

0
On

I have slightly modified your code as I am running in Xcode 7 beta and Swift 2.0

func hex2ascii (example: String) -> String
{

    var chars = [Character]()

    for c in example.characters
    {
        chars.append(c)
    }

    let numbers =  stride(from: 0, to: chars.count, by: 2).map{
                strtoul(String(chars[$0 ..< $0+2]), nil, 16)
    }

    var final = ""
    var i = 0

    while i < numbers.count {
        final.append(Character(UnicodeScalar(Int(numbers[i]))))
        i++
    }

    return final
}

var str = hex2ascii("736c65657020616e6420626174746572206c65")

print("string is \(str)")

This is printing the required output, but see the input, there was an extraneous 01 in your input, and I have removed it and I am getting the output-

string is sleep and batter le

0
On

SWIFT 4:

func hex2ascii (example: String) -> String {

    var chars = [Character]()

    for c in example.characters {
        chars.append(c)
    }

    let numbers =  stride(from: 0, to: chars.count, by: 2).map{
        strtoul(String(chars[$0 ..< $0+2]), nil, 16)
    }

    var final = ""
    var i = 0

    while i < numbers.count {
        final.append(Character(UnicodeScalar(Int(numbers[i]))!))
        i += 1
    }

    return final
}
1
On
func hex2ascii (example: String) -> String
{
var numbers = [UInt8]()
var from = example.startIndex
while from != example.endIndex
{
    let to = from.advancedBy(2, limit: example.endIndex)
    numbers.append(UInt8(example[from ..< to], radix: 16) ?? 0)
    from = to
}

var final = ""
var i = 0

while i < numbers.count {
    final.append(Character(UnicodeScalar(Int(numbers[i]))))
    i+=1
}

return final
}

var str = hex2ascii("736c65657020616e6420626174746572206c65")

print("string is \(str)")