Need quick StringToHex() function

Everything else that doesn't fall into one of the other PB categories.
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Need quick StringToHex() function

Post by Kukulkan »

Hello,

I'm currently using the StringToHex() function below. But I think it should be much faster. Can you help?

The rules:
- Cross plattform
- Single Byte and Unicode capable
- In unicode mode, the unicode string must get converted to UTF8 first.

This is my attempth:

Code: Select all

EnableExplicit

; Copies string to single byte memory (make unicode to utf8)
Macro getSBStringCopy(orig, copy)
  CompilerIf #PB_Compiler_Unicode
    Protected copy.s = Space(StringByteLength(orig) * 2)
    ; make sure the result is null terminated
    FillMemory(@copy, StringByteLength(copy), 0)
    PokeS(@copy, orig, -1, #PB_UTF8)
  CompilerElse
    Protected copy.s = orig
  CompilerEndIf
EndMacro

; Converts a string in hex notation at (each byte to a hex code)
Procedure.s StringToHex(Original.s)
  Protected Ergebnis.s = ""
  Protected x.i = 0
  Protected Dummy.s = ""
  getSBStringCopy(Original, sbOriginal)
  For x.i = 1 To StringByteLength(sbOriginal.s)
    Dummy.s = Dummy.s + RSet(Hex(PeekB(@sbOriginal + x - 1), #PB_Byte), 2, "0")
    If Len(Dummy.s) > 500
      Ergebnis.s = Ergebnis.s + Dummy.s
      Dummy.s = ""
    EndIf
  Next
  Ergebnis.s = Ergebnis.s + Dummy.s
  ProcedureReturn Ergebnis.s
EndProcedure

Define Test.s = Space(100000)
Define start.i = ElapsedMilliseconds()
Define Result.s = StringToHex(Test.s)
Define ende.i = ElapsedMilliseconds()
MessageRequester("Test", "Needed " + Str(ende.i - start.i) + "ms")
End
By the way, I'm also interested in the reverse function if it also fits the rusel above :-)

Thank you,

Kukulkan
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Need quick StringToHex() function

Post by wilbert »

Do you want a solution using only PB commands or is ASM allowed ?
If you want the generated hex data to be stored somewhere, it might be best to always convert to UTF8 (both ascii and unicode).
Windows (x64)
Raspberry Pi OS (Arm64)
Little John
Addict
Addict
Posts: 4869
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Need quick StringToHex() function

Post by Little John »

I have written code for MemoryToHex and HexToMemory conversion here (you'll have to add conversion from/to UTF-8 yourself). Other people have posted code and links in that thread, too. So you might find something there that is useful for you. :-)
Last edited by Little John on Mon Mar 18, 2013 3:17 pm, edited 1 time in total.
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Need quick StringToHex() function

Post by Kukulkan »

wilbert wrote:Do you want a solution using only PB commands or is ASM allowed ?
Hm. Best would be without ASM. So I can understand and convert to x64, other plattform with no problems later.
wilbert wrote:If you want the generated hex data to be stored somewhere, it might be best to always convert to UTF8 (both ascii and unicode).
Good idea but not needed in my case. If single byte version, there must be no encoding as my single byte strings are already utf8 encoded versions.
Little John wrote:I have written code for MemoryToHex and HexToMemory conversion here (it shouldn't be to hard to add string conversion to/from UTF-8). Other people have posted code and links in that thread, too. So you might find something there that is useful for you. :-)
I already found this thread but I thought it was not that optimized for my special need. I need to encode a string (single byte or unicode converted to utf8) to a new string which contains hex. The functions in that thread are needing much conversion with PeekS() and PokeS() etc...

Kukulkan
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Need quick StringToHex() function

Post by wilbert »

Does this work for you ?

Code: Select all

EnableExplicit

; Converts a string in hex notation at (each byte to a hex code)
Procedure.s StringToHex(Original.s)
  Protected Result.s, ResultLen, i, *In.Ascii
  
  ; build static lookup table
  Static Dim Table.l(256)
  If Table(0) = 0
    While i < 256
      PokeS(@Table(i), Right(Hex(256 + i), 2))
      i + 1  
    Wend
  EndIf
  
  ; set some variables and convert to utf8 if required
  CompilerIf #PB_Compiler_Unicode
    i = StringByteLength(Original, #PB_UTF8)
    Result = Space(i << 1)
    *In = @Result + i * 3
    PokeS(*In, Original, -1, #PB_UTF8) 
    Protected *Out.Long = @Result
  CompilerElse
    i = Len(Original)
    Result = Space(i << 1)    
    *In = @Original
    Protected *Out.Word = @Result
  CompilerEndIf
  
  ; conversion loop
  While i
    CompilerIf #PB_Compiler_Unicode
      *Out\l = Table(*In\a)
      *Out + 4
    CompilerElse
      *Out\w = Table(*In\a)
      *Out + 2
    CompilerEndIf
    *In + 1
    i - 1
  Wend
  
  ProcedureReturn Result  
EndProcedure


; test the procedure
Define Test.s = Space(100000)
Define start.i = ElapsedMilliseconds()
Define Result.s = StringToHex(Test.s)
Define ende.i = ElapsedMilliseconds()
MessageRequester("Test", "Needed " + Str(ende.i - start.i) + "ms")
End
Reverse function (built for speed, no check for invalid characters)

Code: Select all

; Converts hex notation to a string (each hex code to a byte)
Procedure.s HexToString(Original.s)
  Protected i.a, n.a, *In.Ascii = @Original
  Protected *Out.Ascii = *In
  
  i = *In\a
  While i
    i & 31
    If i < 7
      i + 9
    Else
      i & 15
    EndIf
    If n > 15
      *Out\a = n << 4 | i
      *Out + 1
      n = 0 
    Else
      n = i | 16
    EndIf
    *In + SizeOf(Character)
    i = *In\a
  Wend
  *Out\a = 0
  
  CompilerIf #PB_Compiler_Unicode
    ProcedureReturn PeekS(@Original, -1, #PB_UTF8)
  CompilerElse
    ProcedureReturn Original
  CompilerEndIf
EndProcedure
Last edited by wilbert on Tue Mar 19, 2013 8:27 am, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Thunder93
Addict
Addict
Posts: 1790
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Need quick StringToHex() function

Post by Thunder93 »

Good job Wilbert, thanks.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Thade
Enthusiast
Enthusiast
Posts: 266
Joined: Sun Aug 03, 2003 12:06 am
Location: Austria

Re: Need quick StringToHex() function

Post by Thade »

A lot of code for things you can do with one line of code :?:
Conversions from Hex and to Hex are supported with Val() and Hex()
This should be the quickest StringToHex

Code: Select all

Result.q=Val("$"+YourHexstring.s)
or with #PB_Byte ... #PB_Unicode

Code: Select all

Result.s=Hex(Val(YourDecimalstring.s))
.
--------------
Yes, its an Irish Wolfhound.
Height: 107 cm; Weight: 88 kg
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Need quick StringToHex() function

Post by wilbert »

Thade wrote:A lot of code for things you can do with one line of code :?:
You missed the point.

Code: Select all

Debug StringToHex("PureBasic"); => "507572654261736963"
Debug HexToString("507572654261736963"); => "PureBasic"
Windows (x64)
Raspberry Pi OS (Arm64)
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Need quick StringToHex() function

Post by rsts »

Nice code wilbert.

Added to toolbox. Thanks.
Little John
Addict
Addict
Posts: 4869
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Need quick StringToHex() function

Post by Little John »

Kukulkan wrote:I need to encode a string (single byte or unicode converted to utf8) to a new string which contains hex. The functions in that thread are needing much conversion with PeekS() and PokeS() etc...
I know that you need to encode a string. Strings are easily handled by those procedures as well, because with @ we can get their memory addresses. In ASCII mode, there is no PeekS() or PokeS() requiered at all. In Unicode mode, according to your needs, one PokeS() would be required ...
It is pretty fine for me when you do not use those functions, but I don't want the forum readers to get a wrong impression about them.
User avatar
Kukulkan
Addict
Addict
Posts: 1422
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Need quick StringToHex() function

Post by Kukulkan »

Whow wilbert,

thank you! :D This is really fast (only 16ms instead of 4300ms)!

I will use the new function now and this really speeds up my program!

Anyway, the comment of Little John makes me curious. How would such implementation look like?

Kukulkan
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Need quick StringToHex() function

Post by davido »

Hi wilbert,

Thank you for sharing your code! Lots to learn - must study it carefully. :D

Astonishing speed for string manipulation. :o
DE AA EB
User avatar
flaith
Enthusiast
Enthusiast
Posts: 704
Joined: Mon Apr 25, 2005 9:28 pm
Location: $300:20 58 FC 60 - Rennes
Contact:

Re: Need quick StringToHex() function

Post by flaith »

:shock: Nice piece of code
“Fear is a reaction. Courage is a decision.” - WC
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Need quick StringToHex() function

Post by wilbert »

davido wrote:Astonishing speed for string manipulation. :o
That's because the main loop is kept very simple and doesn't call any string manipulation functions. :D
Little John wrote:Anyway, the comment of Little John makes me curious. How would such implementation look like?
As far as I understand the routines created by Little John focus on versatility (you can control a lot of output options) while I focused on speed alone.
But maybe he can explain better himself.
Windows (x64)
Raspberry Pi OS (Arm64)
Little John
Addict
Addict
Posts: 4869
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Need quick StringToHex() function

Post by Little John »

Hello Wilbert!
wilbert wrote:As far as I understand the routines created by Little John focus on versatility (you can control a lot of output options) while I focused on speed alone.
But maybe he can explain better himself.
I think it's not possible to explain it better. :-)
Post Reply