LOCAL Demo AS Base32
m.Demo = CREATEOBJECT("Base32")
? m.Demo.Encode(0hdf235768fe4365e6fa3a0a49325d14fb1bc24be1)
? m.Demo.Encode("Hello, world")
DEFINE CLASS Base32 AS Custom
Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
FUNCTION Encode (Source AS String) AS String
LOCAL ToEncode AS String
LOCAL SourceSegment AS String
LOCAL SegmentSize AS Integer
LOCAL EncodedIndex AS Integer
LOCAL ARRAY EncodedSegment(8)
LOCAL Encoded AS String
m.Encoded = ""
m.SourceSegment = LEFT(m.Source, 5)
m.ToEncode = SUBSTR(m.Source, 6)
DO WHILE LEN(m.SourceSegment) > 0
STORE .NULL. TO m.EncodedSegment
m.SegmentSize = LEN(m.SourceSegment)
IF m.SegmentSize = 5
m.EncodedSegment(8) = BITAND(ASC(RIGHT(m.SourceSegment, 1)), 0x1f)
m.EncodedSegment(7) = BITRSHIFT(BITAND(ASC(RIGHT(m.SourceSegment, 1)), 0xe0), 5)
ENDIF
IF m.SegmentSize >= 4
m.EncodedSegment(7) = BITOR(BITLSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 4, 1)), 0x03), 3), NVL(m.EncodedSegment(7), 0))
m.EncodedSegment(6) = BITRSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 4, 1)), 0x7c), 2)
m.EncodedSegment(5) = BITRSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 4, 1)), 0x80), 7)
ENDIF
IF m.SegmentSize >= 3
m.EncodedSegment(5) = BITOR(BITLSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 3, 1)), 0x0f), 1), NVL(m.EncodedSegment(5), 0))
m.EncodedSegment(4) = BITRSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 3, 1)), 0xf0), 4)
ENDIF
IF m.SegmentSize >= 2
m.EncodedSegment(4) = BITOR(BITLSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 2, 1)), 0x01), 4), NVL(m.EncodedSegment(4), 0))
m.EncodedSegment(3) = BITRSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 2, 1)), 0x3e), 1)
m.EncodedSegment(2) = BITRSHIFT(BITAND(ASC(SUBSTR(m.SourceSegment, 2, 1)), 0xc0), 6)
ENDIF
m.EncodedSegment(2) = BITOR(BITLSHIFT(BITAND(ASC(LEFT(m.SourceSegment, 1)), 0x07), 2), NVL(m.EncodedSegment(2), 0))
m.EncodedSegment(1) = BITRSHIFT(BITAND(ASC(LEFT(m.SourceSegment, 1)), 0xf8), 3)
FOR m.EncodedIndex = 1 TO 8
m.Encoded = m.Encoded + SUBSTR(This.Alphabet, NVL(m.EncodedSegment(m.EncodedIndex), 32) + 1, 1)
ENDFOR
m.SourceSegment = LEFT(m.ToEncode, 5)
m.ToEncode = SUBSTR(m.ToEncode, 6)
ENDDO
RETURN m.Encoded
ENDFUNC
ENDDEFINE