Page 1 of 2
Another Hex() complementary function
Posted: Sun Apr 03, 2005 6:14 pm
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
Posted: Mon Apr 04, 2005 12:54 pm
by Bonne_den_kule
Is this a kind of Hex2Bin?
Posted: Tue Apr 05, 2005 6:10 pm
by Psychophanta
Bonne_den_kule wrote:Is this a kind of Hex2Bin?
Not exactly. It is a Hex2Dec function

Posted: Tue Apr 05, 2005 8:40 pm
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)
Posted: Wed Apr 06, 2005 10:48 am
by Froggerprogger
Here are some more versions. (German forum, but PB-code speaks for itself...

)
http://forums.purebasic.com/german/viewtopic.php?t=384
At the second page there's a pure ASM-procedure, too...
Posted: Wed Apr 06, 2005 10:54 am
by gnozal
It's not exactly the same I think, the purpose here is to store (hexadecimal coded) bytes into memory.
Posted: Wed Apr 06, 2005 11:19 am
by Froggerprogger
Err. Yes, I just read 'Hex2Dec' and started my posting, sorry...
@Psychophanta
Nice! And the other way round ?
ValByteSequenceToHexByteString () ?

Posted: Fri Apr 08, 2005 7:54 am
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
Posted: Fri Apr 08, 2005 9:46 pm
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
Posted: Fri Apr 15, 2005 7:55 am
by Psychophanta
Oh!, sorry, but i have problems accessing forums:
http://forums.purebasic.com/ 
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
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
Posted: Thu May 05, 2005 4:09 am
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

Posted: Thu May 05, 2005 1:38 pm
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

Posted: Thu May 05, 2005 10:31 pm
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?
Posted: Fri May 06, 2005 3:21 am
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?
Posted: Fri May 06, 2005 7:55 am
by blueznl
yes, i think so

but isn't that exactly what x_hextomem() posted a little earlier does?