Need quick StringToHex() function

Everything else that doesn't fall into one of the other PB categories.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: Need quick StringToHex() function

Post by SFSxOI »

Wilbert's code is very nice, fast too, thanks Wilbert :)


If anyone needs something to check for valid hex digits you can use regular expressions also, like this using the POSIX character class for hex instead of doing the [a-fA-F0-9] thing:

Code: Select all

Procedure IsHex(in_str.s)
  rex_ishex = CreateRegularExpression(#PB_Any,"^[[:xdigit:]]+$")
  is_hex.b = MatchRegularExpression(rex_ishex, in_str)
  FreeRegularExpression(rex_ishex)
  ProcedureReturn is_hex
EndProcedure

; returns #True (1) if character is valid hex, #False (0) if not
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Need quick StringToHex() function

Post by Joris »

Hi,

I have a strange problem, probably related to my PB-settings, but I don't know how to fix it.
If I use Wilbert's HexToString procedure above, in my source it works very fine (outside the pbi-file). Thanks Wilbert.
If placed inside the pbi like below, it gives a wrong result in the saved file.
Of coarse I can remove it from the pbi and place it inside my 'working source', but what causes this problem.
I'm quit sure it has something todo with #PB_Compiler_Unicode, but how to set it right ?
The result in the file should look the same in a hex-editor (like UltraEdit) as the string send.

Thanks.

Code: Select all

XIncludeFile "String Convertie.pbi"   ;in here is the HexToString procedure

Global s.s = "F043104C0839212BF7"
s=HexToString("F043104C0839212BF7")

If CreateFile(0, "C:\test.dat")           
  WriteData(0, @s, Len(s))
  CloseFile(0)                          
Else
  Debug "may not create the file!"
EndIf
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Need quick StringToHex() function

Post by Joris »

I suppose my problem above can only be solved if not activating the "Create Unicode executable".
I understand Unicode needs two bytes for a single character, ASCII only one.
Yet, still I don't understand why the problem arrives and how to work uniformly ?

Probably best would be always Unicode and giving this result "00F0 0043 0010 004C 0008 0039 0021 002B 00F7" instead of "F0 43 10 4C 08 39 21 2B F7", but this could cause a big problem as the hardware needs ASCII, so I may not activate "Create Unicode executable" ?
Yeah, sorry to if it seems stupid but I'm not used to this and so still confused.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Need quick StringToHex() function

Post by Danilo »

And if you replace

Code: Select all

WriteData(0, @s, Len(s))
with

Code: Select all

WriteString(0,s,#PB_Ascii)
:?:

WriteData(0, @s, Len(s)) writes only half of Unicode strings.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Need quick StringToHex() function

Post by StarBootics »

When I run this code in Unicode Mode :

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

Global Original.s = "F043104C0839212BF7"
Debug Original
String.s = HexToString(Original)

If Trim(String) <> ""
  Debug String
Else
  Debug "Empty String"
EndIf
I get this in the debugger output:
F043104C0839212BF7
Empty String
This is a way to write a string as Data whatever if you are compiling in Ascii or Unicode. Indeed if you create the file in Ascii you have to read it in Ascii.

Code: Select all

Procedure WriteStringEx(FileID.l, String.s)
  
  WriteLong(FileID, SizeOf(Character) * Len(String))
  WriteData(FileID, @String, SizeOf(Character) * Len(String))

EndProcedure 

Procedure.s ReadStringEx(FileID.l)
  
  String.s = Space(ReadLong(FileID))
  ReadData(FileID, @String, Len(String))
  
  ProcedureReturn String
EndProcedure 
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Need quick StringToHex() function

Post by Joris »

Danilo it gives the same result.
It seems really related to the compiler option "Create Unicode executable".
If activating "Create Unicode executable" the output is wrong, with yours and Wilbert's sollution : => 43 10 4C 08 39 21 2B
Deactivate "Create Unicode executable" and the result is ok : => F0 43 10 4C 08 39 21 2B F7

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

Global s.s = "F043104C0839212BF7"
s=HexToString("F043104C0839212BF7")

If CreateFile(0, "e:\test.syx")           ; we create a new text file...
  WriteString(0,s,#PB_Ascii)
  ;WriteData(0, @s, Len(s))
  CloseFile(0)                         ; close the previously opened file and so store the written data
Else
  Debug "may not create the file!"
EndIf

Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Need quick StringToHex() function

Post by StarBootics »

I forget to mention, I'm under Ubuntu Gnome 14.10 x64 and PureBasic 5.31 x64.
I don't understand why I get an empty string, strange...

Beat regards
StarBootics
The Stone Age did not end due to a shortage of stones !
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 »

Try to replace #PB_UTF8 in this line from the HexToString procedure
ProcedureReturn PeekS(@Original, -1, #PB_UTF8)
with #PB_Ascii
The hex codes you present don't seem to be a utf8 string.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Need quick StringToHex() function

Post by Danilo »

Joris wrote:Danilo it gives the same result.
I didn't look at the procedure before. Just said that "WriteData(0, @s, Len(s))" cannot give the same result for ASCII and Unicode.

Changed the procedure a bit now, hope it is still correct for all cases you need:

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.Character = @Original
  Protected *Out.Ascii = *In
  
  i = *In\c
  While i
    i & 31
    If i < 7
      i + 9
    Else
      i & 15
    EndIf
    If n > 15
      *Out\a = n << 4 | i
      *Out + SizeOf(Character)
      n = 0 
    Else
      n = i | 16
    EndIf
    *In + SizeOf(Character)
    i = *In\c
  Wend
  *Out\a = 0
  
  CompilerIf #PB_Compiler_Unicode
    ProcedureReturn Original;PeekS(@Original, -1, #PB_UTF8)
  CompilerElse
    ProcedureReturn Original
  CompilerEndIf
EndProcedure

Global s.s = "F043104C0839212BF7"
s=HexToString("F043104C0839212BF7")

Debug s

If CreateFile(0, "e:\test.syx")           ; we create a new text file...
  WriteString(0,s,#PB_Ascii)
  ;WriteData(0, @s, Len(s))
  CloseFile(0)                         ; close the previously opened file and so store the written data
Else
  Debug "may not create the file!"
EndIf
Gives me 2 identical files for Asc/Uni, 9 Bytes each: F0 43 10 4C 08 39 21 2B F7
Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Need quick StringToHex() function

Post by Joris »

StarBootics if I run your code here in Unicode mode I get this CL9!+ as debug output (the file output is a better reference). And I'm still under XP32.
But after Wilbert's tip and your SizeOf(Character) * Len(sysex_save) all results are like should, with and without "Create Unicode executable".

Wilbert replacing #PB_UTF8 with #PB_Ascii gives the result like should in both cases. So that UTF8, I must look what that exactly means and should do...
F0 00 43 00 ... etc. in unicode, I understand the double zero stands for the second byte and to me that is ok, in ASCII no double zero, completely ok.

Danilo your code works fine here too and in both cases giving the same result, so that might be the solution. I'm gonna look now how it differs from the previous ones.

Yet, I probably must compile my program without activating "Create Unicode executable" as else would appear that double 00 when saving files.
But then what to do if for example someone creates text-files in unicode format to use in my program ?
How to prevent it goes wrong then ? (Yeah I can/will tell in the help only to use ASCII files, but...)

Does anyone have a little text-file in unicode-format for me ?

Thanks all for helping.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Need quick StringToHex() function

Post by Joris »

Trying to learn and hopefully understanding a bit more about all this... there is a lot... maybe it would be much easier if there are some small sample text-files of all sort format there is to find :
All different encoding forms, BOM, big-endian, little-endian etc.
Besides the PB help a bit more of info here :
http://unicode.org/faq/utf_bom.html#BOM
http://www.ultraedit.com/support/tutori ... icode.html

Thanks
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Post Reply