0

So I have written some swift code that will reverse a hex string but I feel there must be a more elegant way to do it.

Input: "FCDB4B42" Output "424BDBFC"

var string2 = "FCDB4B42" 
// reverse the bytes
print (string2)
var string3 = ""
for i in stride(from: 1, to: string2.count, by: 2).reversed() {
    string3 = string3 + string2[i - 1] + string2[i]
}

print(string3) // 424BDBFC

extension String {
    subscript(idx: Int) -> String {
        String(self[index(startIndex, offsetBy: idx)])
    }
}

The aim is to reverse it in pairs to preserve the byte values in a more elegant way (usually there is a better way than a ForNext loop).

Burf2000
  • 5,001
  • 14
  • 58
  • 117
  • if it's a string, I don't think you can make it much more elegant than that. If you are converting it to hex number eventually anyway, then you can use shift and mask, like in conversion for colors: https://stackoverflow.com/a/24263296/5318223 – timbre timbre Mar 23 '23 at 14:02
  • 1
    I gather you want to reverse it in pairs of Hex digits to preserve byte values? You should say that in your problem statement. – Duncan C Mar 23 '23 at 14:05
  • 1
    Are are you looking for elegant, or fast/memory efficient? Those might be competing goals. If you're dealing with a handful of digits, speed/memory efficiency don't really matter. If you're reversing megabytes of data, the above code might be really slow/run out of memory. – Duncan C Mar 23 '23 at 14:06
  • 3
    I’m voting to close this question because questions about improving code that already works are considered off-topic here. Instead, you should consider asking the question on [codereview.stackexchange.com](https://codereview.stackexchange.com). Before asking your question there, please ensure that you read their [help pages about asking questions](https://codereview.stackexchange.com/help/asking). – Dávid Pásztor Mar 23 '23 at 14:09

1 Answers1

1

I’m not sure it’s better, but this avoids using an extension to add a subscript operator:

extension String {
    func hexReversed() -> String {
        guard count > 2 else { return self }

        var result = ""
        var end = endIndex
   
        while let start = index(end, offsetBy: -2, limitedBy: startIndex) {
            result += self[start..<end]
            end = start
        }
   
        return result
    }
}

func test(_ string: String) {
    print("'\(string)' -> '\(string.hexReversed())'")
} 

test("")
test("F")
test("FC")
test("FCD")
test("FCDB4B4")
test("FCDB4B42")

And prints

'' -> ''
'F' -> 'F'
'FC' -> 'FC'
'FCD' -> 'CD'
'FCDB4B4' -> 'B4B4CD'
'FCDB4B42' -> '424BDBFC'

It’s perhaps debatable what should happen with strings that are odd in length: throw an error, return nil, or fail somewhat gracefully. I went with the latter and will drop the first character if the string length is odd. I think the original solution would drop the last character.

Geoff Hackworth
  • 2,673
  • 1
  • 16
  • 16