Faster DecodeHex

Need a means to convert hex to memoryblock faster than looping over every two characters and using FromHex. Even on roughly 1MB of data, this takes a long time.

I’m assuming that you’re not putting your input data into its own memory block, but processing it with string/text functions? If so, you should see some major speed improvement if you put the input text into a memory block and then use math operations to do the conversion.

Or use a BinaryStream to do the math for you:

Dim data As MemoryBlock = GetTheData() Dim stream As New BinaryStream(data) Do until stream.EOF Dim char As String = stream.Read(1) Loop

iOS :slight_smile:

This is my current function

Function DecodeHex(Source As Text) As Xojo.Core.MemoryBlock Dim Bytes() As UInt8 For I As Integer = 0 To Source.Length - 2 Step 2 Dim Value As UInt8 = UInt8.FromHex(Source.Mid(I, 2)) Bytes.Append(Value) Next Return New Xojo.Core.MemoryBlock(Bytes) End Function

So you’re suggesting I put the source hex into a MemoryBlock first and… what next? Use Text.FromUnicodeCodepoint to get the pair of hex characters to decode?

I haven’t tested this, but I’d probably do it something like this:

Public Sub mbHexToBin(sHex As Text)
  dim mbIO As MemoryBlock = sHex
  dim mbSize As Int64 = mbIO.Size\\2-1
 'Lookup table is probably fastest
  static lookup() As Integer = Array(0,1,2,3,4,5,6,7,8,9,_
  0,0,0,0,0,0,0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,_
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,11,12,13,14,15)
  for i as Int64 = 0 to mbSize
    dim j as Int64 = i+i
    mbIO.Byte(i)=lookup((mbIO.Byte(j))-48)*16+lookup((mbIO.Byte(j+1))-48)
  next
End Sub

This processes everything in a single memory block, leaving the output binary in the lower half of the memory block.
I’m assuming that each output byte is represented by two input characters (eg., input character pair ‘B6’ corresponds to binary value 182 = 10110110)
If you have a space between each pair of characters then the above code needs a slight modification

Ah, I didn’t realize that would be an issue. It’s not immediately obvious why it should be one, either.

iOS doesnt use the classic framework at all

The thread is posted within Targets > iOS if you were referring to how Norman knew the OP was looking for an iOS solution.

[quote=338505:@Robert Weaver]I haven’t tested this, but I’d probably do it something like this:

Public Sub mbHexToBin(sHex As Text)
  dim mbIO As MemoryBlock = sHex
  dim mbSize As Int64 = mbIO.Size\\2-1
 'Lookup table is probably fastest
  static lookup() As Integer = Array(0,1,2,3,4,5,6,7,8,9,_
  0,0,0,0,0,0,0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,_
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,11,12,13,14,15)
  for i as Int64 = 0 to mbSize
    dim j as Int64 = i+i
    mbIO.Byte(i)=lookup((mbIO.Byte(j))-48)*16+lookup((mbIO.Byte(j+1))-48)
  next
End Sub

This processes everything in a single memory block, leaving the output binary in the lower half of the memory block.
I’m assuming that each output byte is represented by two input characters (eg., input character pair ‘B6’ corresponds to binary value 182 = 10110110)
If you have a space between each pair of characters then the above code needs a slight modification[/quote]
Thanks. I’ll play around with it when I get back to my computer on Sunday.

FYI, I just tested it a few minutes ago, and it appears to work fine. However, be warned that if the input contains any non-Hex characters, you’ll get an OutOfBoundsException when accessing the lookup table.

I haven’t been paying much attention to the new framework since I don’t use or target iOS, so I didn’t realize that using a BinaryStream with a MemoryBlock doesn’t work in the new framework. I’m more than a little surprised that such a feature would be missing.

To add confusion, the documentation for Xojo.IO.BinaryStream seems to contradict Norman’s post.

Same here. For that reason, I almost didn’t reply to this thread, for fear that I’d use some feature that isn’t in the new framework.
I did remember to switch the ‘string’ type to ‘text’ though. :slight_smile: