简体   繁体   中英

Swift Little endian hex value to decimal

I'm having difficulties implementing a function converting hex value(little endian) to decimal value.

So I'm writing function:

func convertHexLittleEndianToDeciaml(input:String) -> (int) 

and Input is always 4 bytes(so 8 characters in input string)

value for convertHexLittleEndianToDeciaml("606d0000") should return 28,000

You can write something like this: (See UPDATEs)

func convertHexLittleEndianToDeciaml(input:String) -> Int32 {
    if let beValue = Int32(input, radix: 16) where input.characters.count == 8 {
        return beValue.byteSwapped
    } else {
        //or `fatalError()` or `return 0` or ...
        return Int32.min
    }
}

print(convertHexLittleEndianToDeciaml("606d0000")) //->28000

UPDATE

Sorry, but the code above have some overflow issue, happens with something like "FF010000":

func convertHexLittleEndianToDeciaml(input:String) -> Int32 {
    if let beValue = UInt32(input, radix: 16) where input.characters.count == 8 {
        return Int32(bitPattern: beValue.byteSwapped)
    } else {
        //or `fatalError()` or `return 0` or ...
        return Int32.min
    }
}

UPDATE2

So, I have found that returning a valid Int32 in error case might cause a bug which cannot easily be found. I recommend you to change the return type to Optional and return nil in error case.

func convertHexLittleEndianToDeciaml(input:String) -> Int32? {
    guard let beValue = UInt32(input, radix: 16) where input.characters.count == 8 else {
        return nil
    }
    return Int32(bitPattern: beValue.byteSwapped)
}

if let value = convertHexLittleEndianToDeciaml("606d0000") {
    print(value) //->28000
} else {
    print("Hex format invalid")
}

Here's a solution that works for longer numbers that I wrote:

func convert(number: String) -> Int {
    var formatted = number
    if number.count <= 16 {
        let difference = 16 - number.count
        for _ in 0..<difference {
            formatted.append("0")
        }
    } else {
        return 0
    }

    let value = UInt64(formatted, radix: 16) ?? 0
    let z = value.byteSwapped
    let final = UInt64(bitPattern: Int64(z))
    return Int(final)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM