Another Hex() complementary function

Share your advanced PureBasic knowledge/code with the community.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Another Hex() complementary function

Post by Psychophanta »

Code updated for 5.20+

Code: Select all

;This function converts a given Hex string (.s) to a byte sequence stored in a given base address of sequential memory:
Procedure.b HexByteStringToValByteSequence(HexString.s,*mem.Byte)
  Define Nibbles, t, c.w, HexString.s 
  Nibbles = Len(HexString)
  If Nibbles & 1 : HexString = "0" + HexString : Nibbles + 1 : EndIf
  For t = 1 To Nibbles
    c = Asc(Mid(HexString, t, 1))
    If c < '0' Or (c > '9' And c < 'A') Or (c > 'F' And c < 'a') Or c > 'f'
      ProcedureReturn 0
    EndIf
    If c > '9' : c = (c & $5F) - $07 : EndIf
    c - '0'
    If t & 1
      *mem\b = c << 4
    Else
      *mem\b | c
      *mem + 1
    EndIf
  Next
  ProcedureReturn 1
EndProcedure

;Test it: 
*r = AllocateMemory(40) 
d.s = "e567abd7fabad8762348eeeedabbaccc5c6c7300a77844488a99c00c98f88f77e77a4" 
If HexByteStringToValByteSequence(d, *r) 
  For t = 0 To 39 
    Debug Hex(PeekB(*r + t)&$FF) 
  Next 
EndIf
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Bonne_den_kule
Addict
Addict
Posts: 841
Joined: Mon Jun 07, 2004 7:10 pm

Post by Bonne_den_kule »

Is this a kind of Hex2Bin?
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Bonne_den_kule wrote:Is this a kind of Hex2Bin?
Not exactly. It is a Hex2Dec function :)
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

never could resist a challenge :-)

(and i think this is slightly more readable and perhaps a little faster?)

Code: Select all

Procedure x_hextomem(m.l,s.s)
  Protected a.l, b.l, p.l, c.l, l.l
  ;
  p = @s
  c = 0
  l = Len(s)
  ;
  If Left(s,1) = "$"
    p = p+1
  EndIf
  ;
  While c+1 < l
    a = PeekB(p)-48
    If a>10
      a = a-7
    EndIf
    b = PeekB(p+1)-48
    If b > 10
      b = b-7
    EndIf
    PokeB(m+q,a*16+b)
    p = p+2
    q = q+1
    c = c+2
  Wend
EndProcedure

m = AllocateMemory(1024)
s.s = "A0AAFF"
x_hextomem(m,s)
Debug Hex(PeekB(m) & $FF)
Debug Hex(PeekB(m+1) & $FF)
Debug Hex(PeekB(m+2) & $FF)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Froggerprogger
Enthusiast
Enthusiast
Posts: 423
Joined: Fri Apr 25, 2003 5:22 pm
Contact:

Post by Froggerprogger »

Here are some more versions. (German forum, but PB-code speaks for itself... :wink: )
http://forums.purebasic.com/german/viewtopic.php?t=384

At the second page there's a pure ASM-procedure, too...
%1>>1+1*1/1-1!1|1&1<<$1=1
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Froggerprogger wrote:Here are some more versions. (German forum, but PB-code speaks for itself... :wink: )
http://forums.purebasic.com/german/viewtopic.php?t=384

At the second page there's a pure ASM-procedure, too...
It's not exactly the same I think, the purpose here is to store (hexadecimal coded) bytes into memory.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Froggerprogger
Enthusiast
Enthusiast
Posts: 423
Joined: Fri Apr 25, 2003 5:22 pm
Contact:

Post by Froggerprogger »

Err. Yes, I just read 'Hex2Dec' and started my posting, sorry...
@Psychophanta
Nice! And the other way round ?
ValByteSequenceToHexByteString () ?
:)
%1>>1+1*1/1-1!1|1&1<<$1=1
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

if it's about *converting* hex to dec (which wasn't the point in this case :-)) you could use this perhaps... hex, oct, bin...

Code: Select all

Procedure.l x_val(string.s)
  Global x_val_type.l
  Protected p.l, l.l, b.l, t.l, c.l, s.l, m.l, p0.l
  ;
  ; *** as normal val() except it accepts also &H &O &0 &B % \ $ 0X
  ;
  string = UCase(Trim(string))
  l = Len(string)
  p = @string
  p0 = p
  s = PeekB(p) & $FF
  t = 0
  ;
  If s = '-'
    m = -1
    p = p+1
    s = PeekB(p) & $FF
  Else
    m = 1
    If s = '+'
      p = p+1
      s = PeekB(p) & $FF
    EndIf
  EndIf
  ;
  If s = '$'
    p = p+1
    b = 16
  ElseIf s = '%'
    p = p+1
    b = 2
  ElseIf s = '\'
    p = p+1
    b = 8
  ElseIf Left(string,2) = "&B"
    p = p+2
    b = 2
  ElseIf Left(string,2) = "&O"
    p = p+2
    b = 8
  ElseIf Left(string,2) = "&0"
    p = p+2
    b = 8
  ElseIf Left(string,2) = "&H"
    p = p+2
    b = 16
  ElseIf Left(string,2) = "0X"
    p = p+2
    b = 16
    ;
    ; ElseIf Left(string,1) = "0"           ; i don't like this one, as i often use
    ;    p = p+1                            ; preceding zeroes in front of decimals while
    ;    b = 8                              ; c(++) would turn those into octals... brrr...
    ;                                       ; well, it's up to you to uncomment these lines 
  Else
    b = 10
  EndIf
  ;
  While p < p0+l
    c = (PeekB(p) & $FF) - 48
    p = p+1
    If c > 9
      c = c - 7
    EndIf
    If c >= 0 And c < b
      t = t*b+c
    Else
      p = p+l
    EndIf
  Wend
  t = t * m
  x_val_type = b
  ;
  ProcedureReturn t
EndProcedure
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

and the counterpart...

Code: Select all

Procedure.s x_peekhex(addr.l,Length.l)                              ; read a sequence of bytes from mem and store them in hex format in a string
  Protected s.s, b.l, n.l
  ;
  ; *** read a sequence of bytes from memory and store them in hex format in a string
  ;
  n = 0
  While n < Length
    b = x_peekb(addr+n)
    s = s+Hex(b)
    n = n+1
  Wend
  ProcedureReturn s
EndProcedure
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Oh!, sorry, but i have problems accessing forums: http://forums.purebasic.com/ :cry: So i was no able to reply until now.
blueznl wrote:never could resist a challenge
(and i think this is slightly more readable and perhaps a little faster?)
I like that :) :wink:
Froggerprogger wrote:Err. Yes, I just read 'Hex2Dec' and started my posting, sorry...
@Psychophanta
Nice! And the other way round ?
ValByteSequenceToHexByteString () ?
:)
Yes, i made it (of course, keep in mind that sequences are treated a big endian, this is raw; from left to right :)
Here is the complete thing:

Code: Select all

;This function converts a given Hex string (.s) to a byte sequence stored in a given base address of sequential memory:
Procedure.b HexByteStringToDecByteSequence(HexString.s,*mem.Byte)
  Nibbles.l=Len(HexString.s)
  If Nibbles.l&1:HexString.s="0"+HexString.s:Nibbles.l+1:EndIf
  For t.l=1 To Nibbles.l
    c.w=Asc(Mid(HexString.s,t.l,1))
    If c.w<'0' Or (c.w>'9' And c.w<'A') Or (c.w>'F' And c.w<'a') Or c.w>'f'
      ProcedureReturn 0
    EndIf
    If c.w>'9':c.w=(c.w&$5F)-$07:EndIf
    c.w-'0'
    If t.l&1
      *mem\b=c.w<<4
    Else
      *mem\b|c.w
      *mem+1
    EndIf
  Next
  ProcedureReturn 1
EndProcedure
;Test it:
*d.b=AllocateMemory(22)
HexByteStringToDecByteSequence("7e5d772777c7884ab7ebebcd8fabada",*d.b)
For t=1 To 22
  Debug Hex(PeekB(*d.b+t-1)&$FF)
Next

;********************************************************************************************
;This function converts a byte sequence stored in a given base address of sequential memory to a Hex string (.s):
Procedure DecByteSequenceToHexByteString(*seq.Byte,length.l,*HexString.Byte)
  For t.l=1 To length.l
    *HexString\b=Asc(Hex((*seq\b>>4)&$0F)); <-HighNibble
    *HexString+1
    *HexString\b=Asc(Hex(*seq\b&$0F)); <-LowNibble
    *HexString+1
    *seq+1
  Next
  *HexString\b=0
EndProcedure
;Test it:
st.s=Space(22*2)
DecByteSequenceToHexByteString(*d.b,22,@st.s)
Debug st.s
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

Psychophanta - I really really like this but could you show me how to get it to work if the hex values are stored as WORD and not BYTE values? Like...

$3040
$3470

= 30403470


Like a HexWordStringToDecWordSequence?

I have a project in mind that this would help a lot in! Thanks as always for the nice tips & tricks :D
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Xombie wrote:...how to get it to work if the hex values are stored as WORD and not BYTE values?
The functions above do only work for byte sequenced strings. To do it for WORD (little-endian) strings you need to modify it a little bit.
I'll try to get time to put the "Word little-endian" here. At least blueznl or anyone do it first :wink:
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

hey, my routine already does little endian, doesn't it?

$12345678 is turned into $12 $34 $56

or do i have the two terms mixed up? is $34 $12 $78 $56 what you want?
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

I'll try to be more clear. My goal is to read in unicode hexidecimal values into memory. Like $3056 is the character ざ and $306E is the character の, etc... So if I'm working with unicode functions through the winapi (which require null terminated strings) I could pass $3056306E and get the string in memory with the characters as WORDs.

Does that make more sense?
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

yes, i think so :) but isn't that exactly what x_hextomem() posted a little earlier does?
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply