PureBasic Forum
http://forums.purebasic.com/english/

PeekH() and PokeH()
http://forums.purebasic.com/english/viewtopic.php?f=3&t=73948
Page 1 of 1

Author:  swhite [ Wed Nov 06, 2019 1:24 am ]
Post subject:  PeekH() and PokeH()

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

Author:  Josh [ Wed Nov 06, 2019 6:38 am ]
Post subject:  Re: PeekH() and PokeH()

-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.

Author:  mk-soft [ Wed Nov 06, 2019 8:42 pm ]
Post subject:  Re: PeekH() and PokeH()

You build little things like that for yourself.
Code:
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)

Author:  swhite [ Wed Nov 06, 2019 10:06 pm ]
Post subject:  Re: PeekH() and PokeH()

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

Author:  mk-soft [ Thu Nov 07, 2019 1:04 am ]
Post subject:  Re: PeekH() and PokeH()

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

Unicode Version
Code:
;-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

Author:  wilbert [ Thu Nov 07, 2019 7:24 am ]
Post subject:  Re: PeekH() and PokeH()

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:
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

Author:  mk-soft [ Thu Nov 07, 2019 7:17 pm ]
Post subject:  Re: PeekH() and PokeH()

Nice idee Wilbert

Here now PokeH over table... Link: viewtopic.php?f=13&t=73946&p=544255#p544255

Author:  Little John [ Thu Nov 07, 2019 8:27 pm ]
Post subject:  Re: PeekH() and PokeH()

+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).

Author:  wilbert [ Fri Nov 08, 2019 6:40 am ]
Post subject:  Re: PeekH() and PokeH()

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.

Author:  Joris [ Fri Nov 08, 2019 1:26 pm ]
Post subject:  Re: PeekH() and PokeH()

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 ?

Author:  wilbert [ Fri Nov 08, 2019 2:21 pm ]
Post subject:  Re: PeekH() and PokeH()

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:
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.

Author:  Little John [ Fri Nov 08, 2019 3:33 pm ]
Post subject:  Re: PeekH() and PokeH()

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").

Author:  swhite [ Fri Nov 08, 2019 3:48 pm ]
Post subject:  Re: PeekH() and PokeH()

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.

Author:  Joris [ Fri Nov 08, 2019 8:37 pm ]
Post subject:  Re: PeekH() and PokeH()

Wilbert and Little John thanks.

Wilbert I'm already satified, as this coding I can understand (ASM ...hmmm, mostly just admiring).

Author:  Mijikai [ Mon Nov 11, 2019 12:55 pm ]
Post subject:  Re: PeekH() and PokeH()

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

Code:
Code:
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

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/