Base16

Share your advanced PureBasic knowledge/code with the community.
infratec
Always Here
Always Here
Posts: 7588
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Base16

Post by infratec »

Code: Select all

;
; Base16
;
; RFC 3548 / RFC 4648
;
; https://www.purebasic.fr/english/viewtopic.php?t=84910
;

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


DataSection
  Base16EncoderTable:
  Data.a '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
  
  Base16DecoderTable:
  Data.b 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15
  
EndDataSection


Procedure.i Base16EncoderBuffer(*Input, InputSize.i, *Output, OutputSize.i, Flags.i=0)
  
  Protected *InputAscii.Ascii, *InputEnd, *OutputAscii.Ascii, *TableAscii.Ascii
  
  
  If OutputSize >= InputSize * 2
    *InputAscii = *Input
    *InputEnd = *Input + InputSize
    *OutputAscii = *Output
    
    While *InputAscii <> *InputEnd
      *TableAscii = ?Base16EncoderTable + *InputAscii\a >> 4
      *OutputAscii\a = *TableAscii\a
      *OutputAscii + 1
      
      *TableAscii = ?Base16EncoderTable + *InputAscii\a & %1111
      *OutputAscii\a = *TableAscii\a
      *OutputAscii + 1
      
      *InputAscii + 1
    Wend
  EndIf
  
  ProcedureReturn *OutputAscii - *Output
  
EndProcedure




Procedure.s Base16Encoder(*Input, InputSize.i, Flags.i=0)
  
  Protected Base16$, *OutBuffer, Length.i
  
  
  *OutBuffer = AllocateMemory(InputSize * Int(Round(8 / 5, #PB_Round_Up)))
  If *OutBuffer
    Length = Base16EncoderBuffer(*Input, InputSize, *OutBuffer, MemorySize(*OutBuffer), Flags)
    If Length > 0
      Base16$ = PeekS(*OutBuffer, Length, #PB_Ascii)
    EndIf
    FreeMemory(*OutBuffer)
  EndIf
  
  ProcedureReturn Base16$
  
EndProcedure






Procedure.i Base16DecoderBuffer(*Input, InputSize.i, *Output, OutputSize.i)
  
  Protected *InputAscii.Ascii, *InputEnd, *OutputAscii.Ascii, *TableAscii.Ascii
  
  
  *InputAscii = *Input
  *InputEnd = *Input + InputSize
  *OutputAscii = *Output
  
  If OutputSize >= InputSize / 2
    While *InputAscii <> *InputEnd
      *TableAscii = ?Base16DecoderTable + (*InputAscii\a - '0')
      *OutputAscii\a = *TableAscii\a << 4
      *InputAscii + 1
      
      *TableAscii = ?Base16DecoderTable + (*InputAscii\a - '0')
      *OutputAscii\a | *TableAscii\a
      *InputAscii + 1
      
      *OutputAscii + 1
    Wend
  EndIf
  
  ProcedureReturn *OutputAscii - *Output
  
EndProcedure



Procedure.i Base16Decoder(Input$, *Output, OutputSize.i)
  
  Protected Length.i, *Input
  
  
  *Input = Ascii(Input$)
  If *Input
    Length = Base16DecoderBuffer(*Input, MemorySize(*Input) - 1, *Output, OutputSize)
    FreeMemory(*Input)
  EndIf
  
  ProcedureReturn Length
  
EndProcedure





CompilerIf #PB_Compiler_IsMainFile
  
  Define Example$, *Example, *Decoded, *Encoded, Length.i, Encoded$
  
  Example$ = "This is a test string!"
  *Example = UTF8(Example$)
  ;*Example = AllocateMemory(StringByteLength(Example$) + 2)
  ;PokeS(*Example, Example$)
  
  
  Encoded$ = Base16Encoder(*Example, MemorySize(*Example) - 1)
  Debug Encoded$
  
  
  *Decoded = AllocateMemory(1024)
  *Encoded = AllocateMemory(1024)
  
  Length = Base16EncoderBuffer(*Example, MemorySize(*Example) - 1, *Encoded, MemorySize(*Encoded))
  Debug PeekS(*Encoded, Length, #PB_Ascii)
  
  Length = Base16DecoderBuffer(*Encoded, Length, *Decoded, MemorySize(*Decoded))
  Debug PeekS(*Decoded, Length, #PB_UTF8|#PB_ByteLength)
  ;Debug PeekS(*Decoded, Length / 2)
  
  FillMemory(*Decoded, MemorySize(*Decoded))
  Length = Base16Decoder(Encoded$, *Decoded, MemorySize(*Decoded))
  Debug PeekS(*Decoded, Length, #PB_UTF8|#PB_ByteLength)
  
  
CompilerEndIf
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Base16

Post by RASHAD »

@infratec
Thanks
Good work but always little support :)
Egypt my love
infratec
Always Here
Always Here
Posts: 7588
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Base16

Post by infratec »

I'm not a supporter, I'm a programmer :mrgreen:
Post Reply