PeekH() and PokeH()

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

PeekH() and PokeH()

Post by swhite »

Hi

I would like to see two functions that can peek and poke hex strings (i.e. $e17d9f6604a700400082022000950500000000005f). This would avoid problems with ASCII/Unicode string conversion etc.

PeekH(*Buffer,Len.i) : Reads the memory buffer and returns the data in Hex format. Used to read binary data from a memory buffer.

PokeS(*Buffer, Hex.s,len.i) : Puts the hex string into the memory buffer. Used to put binary data into a memory buffer.

Thanks
Simon
Simon White
dCipher Computing
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: PeekH() and PokeH()

Post by Josh »

-1

It is counterproductive if there is a native command for all possible cases that can be handled by a simple procedure. Especially if it's such a special case that's rarely needed.
sorry for my bad english
User avatar
mk-soft
Always Here
Always Here
Posts: 5333
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: PeekH() and PokeH()

Post by mk-soft »

You build little things like that for yourself.

Code: Select all

Structure ByteArray
  b.b[0]
EndStructure

Procedure.s PeekH(*Buffer.ByteArray, Len)
  Protected r1.s, index
  len - 1
  For index = 0 To Len
    r1 + RSet(Hex(*Buffer\b[index], #PB_Byte), 2, "0")
  Next
  ProcedureReturn r1
EndProcedure

value.q = $01020304AABBCCDD

Debug PeekH(@value, 8)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: PeekH() and PokeH()

Post by swhite »

The reason I asked is because I did build my own code for this but I needed it to be much faster. So I figured if PureBasic had such a function it would be much faster than repeated calls to Hex() and RSet().

As far as rarely used, it depends on your application. In the payment industry the EMV readers and Tap & Go readers send all their strings as binary data but most of the routines assume the data has been converted to HEX strings. So it is used all the time when communicating with these devices.

Simon
Simon White
dCipher Computing
User avatar
mk-soft
Always Here
Always Here
Posts: 5333
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: PeekH() and PokeH()

Post by mk-soft »

ASM is also not faster when working with tables. String and Hex functions are always slower

Unicode Version

Code: Select all

;-TOP

Structure ByteArray
  a.a[0]
  b.b[0]
EndStructure

Structure LongArray
  l.l[0]
EndStructure

Structure HexData
  l.l
  w.w
EndStructure

Structure HexArray
  hex.HexData[0]
EndStructure

Global *HexList.HexArray = ?HexList
  
Procedure.s PeekH_V1(*Buffer.ByteArray, Len)
  Protected r1.s, index
  len - 1
  For index = 0 To Len
    r1 + RSet(Hex(*Buffer\b[index], #PB_Byte), 2, "0")
  Next
  ProcedureReturn r1
EndProcedure

Procedure.s PeekH_V2(*Buffer.ByteArray, Len)
  Protected r1.s, *r1.LongArray, index
  r1 = Space(len * 2)
  *r1 = @r1
  len - 1
  For index = 0 To Len
    *r1\l[index] = *HexList\hex[*Buffer\a[index]]\l
  Next
  ProcedureReturn r1
EndProcedure


value.q = $01020304AABBCCDD

start = ElapsedMilliseconds()
For i = 1 To 1000000
  t1.s = PeekH_V1(@value, 8)
Next
ende = ElapsedMilliseconds()

MessageRequester("Time V1", "" + Str(ende - start) + "ms")

start = ElapsedMilliseconds()
For i = 1 To 1000000
  t1.s = PeekH_V2(@value, 8)
Next
ende = ElapsedMilliseconds()

MessageRequester("Time V2", "" + Str(ende - start) + "ms")

DataSection
  HexList:
  Data.s "00"
  Data.s "01"
  Data.s "02"
  Data.s "03"
  Data.s "04"
  Data.s "05"
  Data.s "06"
  Data.s "07"
  Data.s "08"
  Data.s "09"
  Data.s "0A"
  Data.s "0B"
  Data.s "0C"
  Data.s "0D"
  Data.s "0E"
  Data.s "0F"
  Data.s "10"
  Data.s "11"
  Data.s "12"
  Data.s "13"
  Data.s "14"
  Data.s "15"
  Data.s "16"
  Data.s "17"
  Data.s "18"
  Data.s "19"
  Data.s "1A"
  Data.s "1B"
  Data.s "1C"
  Data.s "1D"
  Data.s "1E"
  Data.s "1F"
  Data.s "20"
  Data.s "21"
  Data.s "22"
  Data.s "23"
  Data.s "24"
  Data.s "25"
  Data.s "26"
  Data.s "27"
  Data.s "28"
  Data.s "29"
  Data.s "2A"
  Data.s "2B"
  Data.s "2C"
  Data.s "2D"
  Data.s "2E"
  Data.s "2F"
  Data.s "30"
  Data.s "31"
  Data.s "32"
  Data.s "33"
  Data.s "34"
  Data.s "35"
  Data.s "36"
  Data.s "37"
  Data.s "38"
  Data.s "39"
  Data.s "3A"
  Data.s "3B"
  Data.s "3C"
  Data.s "3D"
  Data.s "3E"
  Data.s "3F"
  Data.s "40"
  Data.s "41"
  Data.s "42"
  Data.s "43"
  Data.s "44"
  Data.s "45"
  Data.s "46"
  Data.s "47"
  Data.s "48"
  Data.s "49"
  Data.s "4A"
  Data.s "4B"
  Data.s "4C"
  Data.s "4D"
  Data.s "4E"
  Data.s "4F"
  Data.s "50"
  Data.s "51"
  Data.s "52"
  Data.s "53"
  Data.s "54"
  Data.s "55"
  Data.s "56"
  Data.s "57"
  Data.s "58"
  Data.s "59"
  Data.s "5A"
  Data.s "5B"
  Data.s "5C"
  Data.s "5D"
  Data.s "5E"
  Data.s "5F"
  Data.s "60"
  Data.s "61"
  Data.s "62"
  Data.s "63"
  Data.s "64"
  Data.s "65"
  Data.s "66"
  Data.s "67"
  Data.s "68"
  Data.s "69"
  Data.s "6A"
  Data.s "6B"
  Data.s "6C"
  Data.s "6D"
  Data.s "6E"
  Data.s "6F"
  Data.s "70"
  Data.s "71"
  Data.s "72"
  Data.s "73"
  Data.s "74"
  Data.s "75"
  Data.s "76"
  Data.s "77"
  Data.s "78"
  Data.s "79"
  Data.s "7A"
  Data.s "7B"
  Data.s "7C"
  Data.s "7D"
  Data.s "7E"
  Data.s "7F"
  Data.s "80"
  Data.s "81"
  Data.s "82"
  Data.s "83"
  Data.s "84"
  Data.s "85"
  Data.s "86"
  Data.s "87"
  Data.s "88"
  Data.s "89"
  Data.s "8A"
  Data.s "8B"
  Data.s "8C"
  Data.s "8D"
  Data.s "8E"
  Data.s "8F"
  Data.s "90"
  Data.s "91"
  Data.s "92"
  Data.s "93"
  Data.s "94"
  Data.s "95"
  Data.s "96"
  Data.s "97"
  Data.s "98"
  Data.s "99"
  Data.s "9A"
  Data.s "9B"
  Data.s "9C"
  Data.s "9D"
  Data.s "9E"
  Data.s "9F"
  Data.s "A0"
  Data.s "A1"
  Data.s "A2"
  Data.s "A3"
  Data.s "A4"
  Data.s "A5"
  Data.s "A6"
  Data.s "A7"
  Data.s "A8"
  Data.s "A9"
  Data.s "AA"
  Data.s "AB"
  Data.s "AC"
  Data.s "AD"
  Data.s "AE"
  Data.s "AF"
  Data.s "B0"
  Data.s "B1"
  Data.s "B2"
  Data.s "B3"
  Data.s "B4"
  Data.s "B5"
  Data.s "B6"
  Data.s "B7"
  Data.s "B8"
  Data.s "B9"
  Data.s "BA"
  Data.s "BB"
  Data.s "BC"
  Data.s "BD"
  Data.s "BE"
  Data.s "BF"
  Data.s "C0"
  Data.s "C1"
  Data.s "C2"
  Data.s "C3"
  Data.s "C4"
  Data.s "C5"
  Data.s "C6"
  Data.s "C7"
  Data.s "C8"
  Data.s "C9"
  Data.s "CA"
  Data.s "CB"
  Data.s "CC"
  Data.s "CD"
  Data.s "CE"
  Data.s "CF"
  Data.s "D0"
  Data.s "D1"
  Data.s "D2"
  Data.s "D3"
  Data.s "D4"
  Data.s "D5"
  Data.s "D6"
  Data.s "D7"
  Data.s "D8"
  Data.s "D9"
  Data.s "DA"
  Data.s "DB"
  Data.s "DC"
  Data.s "DD"
  Data.s "DE"
  Data.s "DF"
  Data.s "E0"
  Data.s "E1"
  Data.s "E2"
  Data.s "E3"
  Data.s "E4"
  Data.s "E5"
  Data.s "E6"
  Data.s "E7"
  Data.s "E8"
  Data.s "E9"
  Data.s "EA"
  Data.s "EB"
  Data.s "EC"
  Data.s "ED"
  Data.s "EE"
  Data.s "EF"
  Data.s "F0"
  Data.s "F1"
  Data.s "F2"
  Data.s "F3"
  Data.s "F4"
  Data.s "F5"
  Data.s "F6"
  Data.s "F7"
  Data.s "F8"
  Data.s "F9"
  Data.s "FA"
  Data.s "FB"
  Data.s "FC"
  Data.s "FD"
  Data.s "FE"
  Data.s "FF"
  Data.w 0
EndDataSection
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: PeekH() and PokeH()

Post by wilbert »

mk-soft wrote:ASM is also not faster when working with tables.
ASM is faster but your PB code is also very fast. :)

By the way, the PB code can be made faster by using a result buffer combined with PeekS.
Example :

Code: Select all

Global Dim HexList.l(255)

Procedure InitHexList()
  Protected i.i
  For i = 0 To 255
    PokeS(@HexList(i), RSet(Hex(i), 2, "0"), 2, #PB_String_NoZero)   
  Next
EndProcedure
InitHexList()

Procedure.s PeekH(*Buffer.Ascii, Len)
  Protected Dim Result.l(Len)
  Protected *Result.Long = @Result()
  While Len
    Len - 1
    *Result\l = HexList(*Buffer\a)
    *Result + 4
    *Buffer + 1
  Wend
  ProcedureReturn PeekS(@Result())
EndProcedure
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mk-soft
Always Here
Always Here
Posts: 5333
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: PeekH() and PokeH()

Post by mk-soft »

Nice idee Wilbert

Here now PokeH over table... Link: viewtopic.php?f=13&t=73946&p=544255#p544255
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: PeekH() and PokeH()

Post by Little John »

+1 for the original request, BTW.

It would be nice to have something like this built-in into PureBasic, especially since those are rather basic functions (no pun intended).
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: PeekH() and PokeH()

Post by wilbert »

Little John wrote:+1 for the original request, BTW.

It would be nice to have something like this built-in into PureBasic, especially since those are rather basic functions (no pun intended).
I agree with the request but I think it would be more logical to have the functions as Base16Encoder / Base16Decoder as the behavior is very similar to the Base64 functions.
Windows (x64)
Raspberry Pi OS (Arm64)
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: PeekH() and PokeH()

Post by Joris »

Wouldn't it be nice if the full string of hex-values can be viewed, each value seperated with a space-character (like in a hex-editor or something) ?
How can this be done best without loosing to much speed ?
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: PeekH() and PokeH()

Post by wilbert »

Joris wrote:Wouldn't it be nice if the full string of hex-values can be viewed, each value seperated with a space-character (like in a hex-editor or something) ?
How can this be done best without loosing to much speed ?
Something like this ?

Code: Select all

Global Dim HexList.l(255)

Procedure InitHexList()
  Protected i.i
  For i = 0 To 255
    PokeS(@HexList(i), RSet(Hex(i), 2, "0"), 2, #PB_String_NoZero)   
  Next
EndProcedure
InitHexList()

Procedure.s PeekH(*Buffer.Ascii, Len)
  Protected Dim Result.l(Len)
  Protected *Result.Long = @Result()
  While Len
    Len - 1
    *Result\l = HexList(*Buffer\a)
    *Result + 4
    *Buffer + 1
  Wend
  ProcedureReturn PeekS(@Result())
EndProcedure

Procedure.s PeekHSeparated(*Buffer.Ascii, Len)
  Protected Dim Result.u(Len * 3)
  Protected *Result.Long = @Result()
  Protected *Separator.Unicode = *Result + 4
  While Len
    Len - 1
    *Result\l = HexList(*Buffer\a)
    *Result + 6
    *Separator\u = 32
    *Separator + 6
    *Buffer + 1
  Wend
  ProcedureReturn PeekS(@Result())
EndProcedure


q.q = $0123456789abcdef
Debug PeekH(@q, 8)
Debug PeekHSeparated(@q, 8)
It is slower.
Asm could be used to speed it up a bit.
Windows (x64)
Raspberry Pi OS (Arm64)
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: PeekH() and PokeH()

Post by Little John »

Joris wrote:Wouldn't it be nice if the full string of hex-values can be viewed, each value seperated with a space-character (like in a hex-editor or something) ?
How can this be done best without loosing to much speed ?
When using PeekHexBytes(), you can optionally define your own separator (e.g. " " or ";") and your own prefix (e.g. "$" or "0x").
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: PeekH() and PokeH()

Post by swhite »

Hi

Base16Encoder/Base16Decoder are both good ideas to me. The idea of having an optional separator for both is also a good idea. I would be willing to sponsor these two functions if Fred was open to the idea. It makes handling ASCII strings in Unicode very easy. I would hope Fred might use Wilbert's high speed methods so the functions are very fast.
wilbert wrote:
Little John wrote:+1 for the original request, BTW.

It would be nice to have something like this built-in into PureBasic, especially since those are rather basic functions (no pun intended).
I agree with the request but I think it would be more logical to have the functions as Base16Encoder / Base16Decoder as the behavior is very similar to the Base64 functions.
Simon White
dCipher Computing
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: PeekH() and PokeH()

Post by Joris »

Wilbert and Little John thanks.

Wilbert I'm already satified, as this coding I can understand (ASM ...hmmm, mostly just admiring).
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: PeekH() and PokeH()

Post by Mijikai »

Here is my try on it :)
Its also uses lookup tables to increase the speed.

Code:

Code: Select all

Procedure.s PeekH(*Buffer.Ascii,BufferSize.i)
  Protected ho.i,hs.s,*hx.String = @ho
  BufferSize + *Buffer
  Repeat
    ho = ?hex + *Buffer\a << 3:hs + *hx\s:*Buffer + 1
  Until *Buffer = BufferSize
  ProcedureReturn hs
  hex:
  !du '00',0,0,'01',0,0,'02',0,0,'03',0,0,'04',0,0,'05',0,0,'06',0,0,'07',0,0,'08',0,0,'09',0,0,'0A',0,0,'0B',0,0,'0C',0,0,'0D',0,0,'0E',0,0,'0F',0,0
  !du '10',0,0,'11',0,0,'12',0,0,'13',0,0,'14',0,0,'15',0,0,'16',0,0,'17',0,0,'18',0,0,'19',0,0,'1A',0,0,'1B',0,0,'1C',0,0,'1D',0,0,'1E',0,0,'1F',0,0
  !du '20',0,0,'21',0,0,'22',0,0,'23',0,0,'24',0,0,'25',0,0,'26',0,0,'27',0,0,'28',0,0,'29',0,0,'2A',0,0,'2B',0,0,'2C',0,0,'2D',0,0,'2E',0,0,'2F',0,0
  !du '30',0,0,'31',0,0,'32',0,0,'33',0,0,'34',0,0,'35',0,0,'36',0,0,'37',0,0,'38',0,0,'39',0,0,'3A',0,0,'3B',0,0,'3C',0,0,'3D',0,0,'3E',0,0,'3F',0,0
  !du '40',0,0,'41',0,0,'42',0,0,'43',0,0,'44',0,0,'45',0,0,'46',0,0,'47',0,0,'48',0,0,'49',0,0,'4A',0,0,'4B',0,0,'4C',0,0,'4D',0,0,'4E',0,0,'4F',0,0
  !du '50',0,0,'51',0,0,'52',0,0,'53',0,0,'54',0,0,'55',0,0,'56',0,0,'57',0,0,'58',0,0,'59',0,0,'5A',0,0,'5B',0,0,'5C',0,0,'5D',0,0,'5E',0,0,'5F',0,0
  !du '60',0,0,'61',0,0,'62',0,0,'63',0,0,'64',0,0,'65',0,0,'66',0,0,'67',0,0,'68',0,0,'69',0,0,'6A',0,0,'6B',0,0,'6C',0,0,'6D',0,0,'6E',0,0,'6F',0,0
  !du '70',0,0,'71',0,0,'72',0,0,'73',0,0,'74',0,0,'75',0,0,'76',0,0,'77',0,0,'78',0,0,'79',0,0,'7A',0,0,'7B',0,0,'7C',0,0,'7D',0,0,'7E',0,0,'7F',0,0
  !du '80',0,0,'81',0,0,'82',0,0,'83',0,0,'84',0,0,'85',0,0,'86',0,0,'87',0,0,'88',0,0,'89',0,0,'8A',0,0,'8B',0,0,'8C',0,0,'8D',0,0,'8E',0,0,'8F',0,0
  !du '90',0,0,'91',0,0,'92',0,0,'93',0,0,'94',0,0,'95',0,0,'96',0,0,'97',0,0,'98',0,0,'99',0,0,'9A',0,0,'9B',0,0,'9C',0,0,'9D',0,0,'9E',0,0,'9F',0,0
  !du 'A0',0,0,'A1',0,0,'A2',0,0,'A3',0,0,'A4',0,0,'A5',0,0,'A6',0,0,'A7',0,0,'A8',0,0,'A9',0,0,'AA',0,0,'AB',0,0,'AC',0,0,'AD',0,0,'AE',0,0,'AF',0,0
  !du 'B0',0,0,'B1',0,0,'B2',0,0,'B3',0,0,'B4',0,0,'B5',0,0,'B6',0,0,'B7',0,0,'B8',0,0,'B9',0,0,'BA',0,0,'BB',0,0,'BC',0,0,'BD',0,0,'BE',0,0,'BF',0,0
  !du 'C0',0,0,'C1',0,0,'C2',0,0,'C3',0,0,'C4',0,0,'C5',0,0,'C6',0,0,'C7',0,0,'C8',0,0,'C9',0,0,'CA',0,0,'CB',0,0,'CC',0,0,'CD',0,0,'CE',0,0,'CF',0,0
  !du 'D0',0,0,'D1',0,0,'D2',0,0,'D3',0,0,'D4',0,0,'D5',0,0,'D6',0,0,'D7',0,0,'D8',0,0,'D9',0,0,'DA',0,0,'DB',0,0,'DC',0,0,'DD',0,0,'DE',0,0,'DF',0,0
  !du 'E0',0,0,'E1',0,0,'E2',0,0,'E3',0,0,'E4',0,0,'E5',0,0,'E6',0,0,'E7',0,0,'E8',0,0,'E9',0,0,'EA',0,0,'EB',0,0,'EC',0,0,'ED',0,0,'EE',0,0,'EF',0,0
  !du 'F0',0,0,'F1',0,0,'F2',0,0,'F3',0,0,'F4',0,0,'F5',0,0,'F6',0,0,'F7',0,0,'F8',0,0,'F9',0,0,'FA',0,0,'FB',0,0,'FC',0,0,'FD',0,0,'FE',0,0,'FF',0,0
EndProcedure

Procedure.i PokeH(*Buffer.Ascii,Hex.s)
  Protected hi.i,*hc.Long,*hx.Long = @Hex
  Repeat
    For hi = 0 To 255:*hc = ?hex + (hi << 2):If *hc\l = *hx\l:*Buffer\a = hi:EndIf:Next
    *Buffer + 1:*hx + 4    
  Until *hx\l = #Null
  ProcedureReturn #Null
  hex:
  !du '00','01','02','03','04','05','06','07','08','09','0A','0B','0C','0D','0E','0F'
  !du '10','11','12','13','14','15','16','17','18','19','1A','1B','1C','1D','1E','1F'
  !du '20','21','22','23','24','25','26','27','28','29','2A','2B','2C','2D','2E','2F'
  !du '30','31','32','33','34','35','36','37','38','39','3A','3B','3C','3D','3E','3F'
  !du '40','41','42','43','44','45','46','47','48','49','4A','4B','4C','4D','4E','4F'
  !du '50','51','52','53','54','55','56','57','58','59','5A','5B','5C','5D','5E','5F'
  !du '60','61','62','63','64','65','66','67','68','69','6A','6B','6C','6D','6E','6F'
  !du '70','71','72','73','74','75','76','77','78','79','7A','7B','7C','7D','7E','7F'
  !du '80','81','82','83','84','85','86','87','88','89','8A','8B','8C','8D','8E','8F'
  !du '90','91','92','93','94','95','96','97','98','99','9A','9B','9C','9D','9E','9F'
  !du 'A0','A1','A2','A3','A4','A5','A6','A7','A8','A9','AA','AB','AC','AD','AE','AF'
  !du 'B0','B1','B2','B3','B4','B5','B6','B7','B8','B9','BA','BB','BC','BD','BE','BF'
  !du 'C0','C1','C2','C3','C4','C5','C6','C7','C8','C9','CA','CB','CC','CD','CE','CF'
  !du 'D0','D1','D2','D3','D4','D5','D6','D7','D8','D9','DA','DB','DC','DD','DE','DF'
  !du 'E0','E1','E2','E3','E4','E5','E6','E7','E8','E9','EA','EB','EC','ED','EE','EF'
  !du 'F0','F1','F2','F3','F4','F5','F6','F7','F8','F9','FA','FB','FC','FD','FE','FF'
EndProcedure
Post Reply