Page 1 of 1
My IsHex procedure
Posted: Mon Oct 11, 2010 11:34 pm
by wallgod
So I wrote this procedure to determine whether or not a given input is valid hexadecimal. Unlike similar methods, this one checks for uppercase or lowercase variants, confirms that the input string is divisible by 2, and allows a list of ignore characters, like spaces etc.
Code: Select all
Procedure IsHex(hex.s, ignore.s="")
Protected LenI.i, x.i
For x = 1 To Len(ignore)
hex = RemoveString(hex, Mid(ignore, x, 1), 1)
Next
LenI = Len(hex)
If LenI % 2 <> 0
ProcedureReturn 0
EndIf
For x = 1 To LenI
If FindString("AaBbCcDdEeFf0123456789", Mid(hex, x, 1), 1) = 0
ProcedureReturn 0
EndIf
Next
ProcedureReturn 1
EndProcedure
Re: My IsHex procedure
Posted: Tue Oct 12, 2010 4:46 am
by idle
nice thanks for sharing
Re: My IsHex procedure
Posted: Tue Oct 12, 2010 5:05 am
by kenmo
Why must its length be a multiple of 2?
Something like 3D4 is valid hex, equivalent to 03D4.
Unless you have a reason otherwise...?
Re: My IsHex procedure
Posted: Tue Oct 12, 2010 7:35 am
by infratec
Hi,
hm...
I extended my version by the 'ignore' stuff. It looks longer, but I think it is more simple.
Decide by yourself
Code: Select all
Procedure IsHex(Hex$, Ignore$ = "")
*HexPtr = @Hex$
*IgnorePtr = @Ignore$
For i = 0 To Len(Hex$) - 1
Help.a = PeekA(*HexPtr + i)
Ignore = #False
For j = 0 To Len(Ignore$) - 1
If Help = PeekA(*IgnorePtr + j)
Ignore = #True
Break
EndIf
Next j
If Not Ignore
If Help < '0' : ProcedureReturn #False : EndIf
If Help > '9'
If Help < 'A' : ProcedureReturn #False : EndIf
If Help > 'F'
If Help < 'a' Or Help > 'f': ProcedureReturn #False : EndIf
EndIf
EndIf
EndIf
Next i
ProcedureReturn #True
EndProcedure
Best regards,
Bernd
Re: My IsHex procedure
Posted: Tue Oct 12, 2010 10:45 am
by PB
Here's my version. Upper or lower case doesn't matter.
No option is provided to remove any characters. Just
a straight test of the supplied string.
Code: Select all
; Returns 1 if string is all hex chars, or 0 if not.
Procedure IsHex(text$)
For p=1 To Len(text$)
c$=Mid(text$,p,1)
If c$<>"0" And Val("$"+c$)=0
s=1 : Break
EndIf
Next
ProcedureReturn 1-s
EndProcedure
Debug IsHex("FF") ; Returns 1
Debug IsHex("0D0a") ; Returns 1
Debug IsHex("abCDef") ; Returns 1
Debug IsHex("C00L d00d!") ; Returns 0
Debug IsHex("abCDefG") ; Returns 0
Debug IsHex("#255") ; Returns 0
Re: My IsHex procedure
Posted: Tue Oct 12, 2010 11:00 am
by blueznl
You could also match it to a regexp...
Code: Select all
Global re_ishex = CreateRegularExpression(#PB_Any,"^[$]?[0-9a-fA-F]+$")
Procedure.i x_ishex(s.s)
ProcedureReturn MatchRegularExpression(re_ishex,s)
EndProcedure
Debug x_ishex("a")
http://www.xs4all.nl/~bluez/purebasic/p ... 26.htm#top
Re: My IsHex procedure
Posted: Tue Oct 12, 2010 11:32 am
by breeze4me
These don't depend on any PB functions.
Code: Select all
;DisableDebugger
Structure CharArray
c.c[0]
EndStructure
Procedure IsHexStrPtr(*string.CharArray, *ignore.CharArray = 0)
Protected i, idx, x, res
If *string
IsHexStrPtr_Loop:
x = *string\c[i]
i + 1
If x = 0 : Goto IsHexStrPtr_Exit : EndIf ;if null character then exit.
If *ignore ;skip over some characters.(case sensitive)
idx = 0
While *ignore\c[idx]
If x = *ignore\c[idx] : Goto IsHexStrPtr_Loop : EndIf
idx + 1
Wend
EndIf
res = 1
If x < '0' : Goto IsHexStrPtr_NotHex : EndIf
If x <= '9' : Goto IsHexStrPtr_Loop : EndIf
x | $20 ;into lowercase character.
If x < 'a' : Goto IsHexStrPtr_NotHex : EndIf
If x <= 'f' : Goto IsHexStrPtr_Loop : EndIf
IsHexStrPtr_NotHex:
res = 0
IsHexStrPtr_Exit:
EndIf
ProcedureReturn res
EndProcedure
Procedure IsHexStr(string.s, ignore.s = "")
Protected i, idx, x, res
Protected *str.CharArray = @string, *ignore.CharArray = @ignore
If string
IsHexStr_Loop:
x = *str\c[i]
i + 1
If x = 0 : Goto IsHexStr_Exit : EndIf ;if null character then exit.
If *ignore ;skip over some characters.(case sensitive)
idx = 0
While *ignore\c[idx]
If x = *ignore\c[idx] : Goto IsHexStr_Loop : EndIf
idx + 1
Wend
EndIf
res = 1
If x < '0' : Goto IsHexStr_NotHex : EndIf
If x <= '9' : Goto IsHexStr_Loop : EndIf
x | $20 ;into lowercase character.
If x < 'a' : Goto IsHexStr_NotHex : EndIf
If x <= 'f' : Goto IsHexStr_Loop : EndIf
IsHexStr_NotHex:
res = 0
IsHexStr_Exit:
EndIf
ProcedureReturn res
EndProcedure
;test.
Debug IsHexStrPtr(0, 0) ;0
Debug IsHexStrPtr(0) ;0
Debug IsHexStrPtr(@"", @"") ;0
Debug IsHexStrPtr(@"", @" ") ;0
Debug IsHexStrPtr(@"") ;0
Debug IsHexStrPtr(@" z", @" ") ;0
Debug IsHexStrPtr(@" ", @" ") ;0
Debug IsHexStrPtr(@" ") ;0
Debug " "
Debug IsHexStrPtr(@"a d 1 9 84fdc1", @" ") ;1
Debug IsHexStrPtr(@"a0 ad fe 99 84", @" ") ;1
Debug IsHexStrPtr(@"a0 ad fe 99 84") ;0
Debug IsHexStrPtr(@"0123456789abcdefABCDEF", @"") ;1
Debug IsHexStrPtr(@"0123456789abcdefABCDEF") ;1
Debug IsHexStrPtr(@"0123456789abcdefABCDEFg", @"") ;0
Debug IsHexStrPtr(@"0123456789abcdefABCDEFg") ;0
Debug IsHexStrPtr(@"0 ", @" ") ;1
Debug IsHexStrPtr(@"0 g", @" ") ;0
Debug IsHexStrPtr(@"0 aaG", @" g") ;0
Debug " "
Debug IsHexStr("", "") ;0
Debug IsHexStr("", " ") ;0
Debug IsHexStr("") ;0
Debug IsHexStr(" z", " ") ;0
Debug IsHexStr(" ", " ") ;0
Debug IsHexStr(" ") ;0
Debug " "
Debug IsHexStr("a d 1 9 84fdc1", " ") ;1
Debug IsHexStr("a0 ad fe 99 84", " ") ;1
Debug IsHexStr("a0 ad fe 99 84") ;0
Debug IsHexStr("0123456789abcdefABCDEF", "") ;1
Debug IsHexStr("0123456789abcdefABCDEF") ;1
Debug IsHexStr("0123456789abcdefABCDEFg", "") ;0
Debug IsHexStr("0123456789abcdefABCDEFg") ;0
Debug IsHexStr("0 ", " ") ;1
Debug IsHexStr("0 g", " ") ;0
Debug IsHexStr("0 aaG", " g") ;0
Re: My IsHex procedure
Posted: Tue Oct 12, 2010 1:10 pm
by wallgod
Here's my updated one, which doesn't require the input's length to be divisible by 2, and also makes sure the input isn't empty (which would have previously returned a false positive).
Code: Select all
Procedure.i IsHex(hex.s,ignore.s="")
Protected x.i
For x=1 To Len(ignore)
hex=RemoveString(hex,Mid(ignore,x,1),1)
Next
If hex=""
ProcedureReturn 0
EndIf
For x=1 To Len(hex)
If FindString("AaBbCcDdEeFf0123456789",Mid(hex,x,1),1)=0
ProcedureReturn 0
EndIf
Next
ProcedureReturn 1
EndProcedure
And I'm very impressed by these two (PB & blueznl):
PB wrote:Code: Select all
Procedure IsHex(text$)
For p=1 To Len(text$)
c$=Mid(text$,p,1)
If c$<>"0" And Val("$"+c$)=0
s=1 : Break
EndIf
Next
ProcedureReturn 1-s
EndProcedure
blueznl wrote:Code: Select all
Global re_ishex = CreateRegularExpression(#PB_Any,"^[$]?[0-9a-fA-F]+$")
Procedure x_ishex(s.s)
ProcedureReturn MatchRegularExpression(re_ishex,s)
EndProcedure
Well done!
Re: My IsHex procedure
Posted: Wed Oct 13, 2010 2:39 am
by kenmo
blueznl wrote:You could also match it to a regexp...
I was waiting for someone to say that.
The hex-checking part is easy with regexs, but how would you go about including the Ignore functionality? (No really, I'd like to know.)
Re: My IsHex procedure
Posted: Wed Oct 13, 2010 12:07 pm
by wallgod
kenmo wrote:blueznl wrote:You could also match it to a regexp...
I was waiting for someone to say that.
The hex-checking part is easy with regexs, but how would you go about including the Ignore functionality? (No really, I'd like to know.)
By removing the ignore characters from the string before checking against the regular expression.

Re: My IsHex procedure
Posted: Wed Oct 13, 2010 3:00 pm
by blueznl
What would you like to ignore? If only a space, then add the space to the acceptable characters. Please give an example...
Re: My IsHex procedure
Posted: Wed Oct 13, 2010 11:07 pm
by kenmo
wallgod wrote:By removing the ignore characters from the string before checking against the regular expression.

Well.... yes.... but I'm wondering how you would write character removal USING a regexp? I just started learning them this past year.
blueznl wrote:What would you like to ignore? If only a space, then add the space to the acceptable characters. Please give an example...
Nothing specific, I just figured you may want to incorporate the functionality in Wallgod's original posted code.
Re: My IsHex procedure
Posted: Thu Oct 14, 2010 7:36 am
by blueznl
Well, I've stopped my fooling around with regexp when it started to get too confusing, so I limited myself to the simple things

Re: My IsHex procedure
Posted: Thu Oct 14, 2010 6:56 pm
by wallgod
kenmo wrote:wallgod wrote:By removing the ignore characters from the string before checking against the regular expression.

Well.... yes.... but I'm wondering how you would write character removal USING a regexp? I just started learning them this past year.
blueznl wrote:What would you like to ignore? If only a space, then add the space to the acceptable characters. Please give an example...
Nothing specific, I just figured you may want to incorporate the functionality in Wallgod's original posted code.
You wouldn't add the ignore characters using a regular expression because that defeats the point of making it customizable by a procedure parameter. Here's an example of how to use the regular expression method coupled with an ignore sequence:
Code: Select all
Global re_ishex = CreateRegularExpression(#PB_Any,"^[$]?[0-9a-fA-F]+$")
Procedure.i x_ishex(s.s,ignore.s="")
Protected x.i
For x=1 To Len(ignore):s=RemoveString(s,Mid(ignore,x,1),1):Next
ProcedureReturn MatchRegularExpression(re_ishex,s)
EndProcedure
Debug x_ishex("x4A:xbf:x0d:x5B:x0F:x0F"); returns 0 {false}
Debug x_ishex("x4A:xbf:x0d:x5B:x0F:x0F", ":x"); returns 1 {true}
Debug x_ishex("4A bf 0d 5B 0F 0F"); returns 0 {false}
Debug x_ishex("4A bf 0d 5B 0F 0F", " "); returns 1 {true}