Base32Coder.st
changeset 4742 476666bdc4a0
parent 4508 3a2fc002271d
equal deleted inserted replaced
4741:bfb8e4d34f3e 4742:476666bdc4a0
       
     1 "{ Encoding: utf8 }"
       
     2 
     1 "
     3 "
     2  COPYRIGHT (c) 2002 by eXept Software AG
     4  COPYRIGHT (c) 2002 by eXept Software AG
     3               All Rights Reserved
     5               All Rights Reserved
     4 
     6 
     5  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
    61    |data1 text data2|
    63    |data1 text data2|
    62 
    64 
    63    data1 := #[0 1 16r7F 16r80 16r81 16rFE 16rFF].
    65    data1 := #[0 1 16r7F 16r80 16r81 16rFE 16rFF].
    64    text := Base32Coder encode:data1.
    66    text := Base32Coder encode:data1.
    65    data2 := Base32Coder decode:text.
    67    data2 := Base32Coder decode:text.
    66    data2  
    68    self assert:(data2 = data1)
    67                                                                 [exEnd]
    69                                                                 [exEnd]
    68 
    70 
    69                                                                 [exBegin]
    71                                                                 [exBegin]
    70    |coder|
    72    |coder|
    71 
    73 
    98    coder nextPutAll:(0 to:200) asByteArray.
   100    coder nextPutAll:(0 to:200) asByteArray.
    99    coder flush.
   101    coder flush.
   100 
   102 
   101    Transcript showCR:(coder contents).
   103    Transcript showCR:(coder contents).
   102                                                                 [exEnd]
   104                                                                 [exEnd]
       
   105                                                                 [exBegin]
       
   106    |bytes encoded decoded|
       
   107 
       
   108    bytes := #[0 0 0] copy.
       
   109    0 to:255 do:[:b1 |
       
   110        Transcript showCR:b1.  
       
   111        bytes at:1 put:b1.  
       
   112        0 to:255 do:[:b2 |
       
   113            bytes at:2 put:b2.  
       
   114            0 to:255 do:[:b3 |
       
   115                bytes at:3 put:b3.  
       
   116                encoded := Base32Coder encode:bytes.
       
   117                decoded := Base32Coder decode:encoded.
       
   118                self assert:(decoded = bytes).
       
   119            ]
       
   120        ]
       
   121    ].
       
   122                                                                 [exEnd]
   103 "
   123 "
   104 ! !
   124 ! !
   105 
   125 
   106 !Base32Coder class methodsFor:'initialization'!
   126 !Base32Coder class methodsFor:'initialization'!
   107 
   127 
   109     "initialize class variables"
   129     "initialize class variables"
   110     
   130     
   111     Base32Mapping isNil ifTrue:[
   131     Base32Mapping isNil ifTrue:[
   112         "33 characters representing the 5-bit values from 0-31 and one pad character"
   132         "33 characters representing the 5-bit values from 0-31 and one pad character"
   113         Base32Mapping := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567='.
   133         Base32Mapping := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567='.
   114         Base32ReverseMapping := ByteArray new:96 withAll:255.
   134         Base32ReverseMapping := self reverseMappingFor:Base32Mapping.
   115         Base32Mapping keysAndValuesDo:[:idx :char|
       
   116             Base32ReverseMapping at:char codePoint put:idx-1.
       
   117         ].
       
   118     ].
   135     ].
   119 
   136 
   120     "
   137     "
       
   138      Base32Mapping := nil.
   121      self initializeMappings
   139      self initializeMappings
   122     "
   140     "
       
   141 
       
   142     "Modified (comment): / 30-09-2018 / 15:39:55 / Claus Gittinger"
       
   143 !
       
   144 
       
   145 mapping
       
   146     ^ Base32Mapping
       
   147 
       
   148     "Created: / 30-09-2018 / 15:31:00 / Claus Gittinger"
       
   149 !
       
   150 
       
   151 reverseMapping
       
   152     ^ Base32ReverseMapping
       
   153 
       
   154     "Created: / 30-09-2018 / 15:30:54 / Claus Gittinger"
   123 ! !
   155 ! !
   124 
   156 
   125 !Base32Coder methodsFor:'encoding'!
   157 !Base32Coder methodsFor:'encoding'!
   126 
   158 
   127 nextPutByte:aByte
   159 nextPutByte:aByte
   136     buffer := (buffer bitShift:8) bitOr:aByte.
   168     buffer := (buffer bitShift:8) bitOr:aByte.
   137     bits := bits + 8 - 5.           "max value of bits = 4 + 8 - 5"
   169     bits := bits + 8 - 5.           "max value of bits = 4 + 8 - 5"
   138 
   170 
   139     bits >= 5 ifTrue:[
   171     bits >= 5 ifTrue:[
   140         "enough bits to write two chars: write the first 5 bits"
   172         "enough bits to write two chars: write the first 5 bits"
   141         stream nextPut:(Base32Mapping at:(buffer rightShift:bits)+1).
   173         stream nextPut:(mapping at:(buffer rightShift:bits)+1).
   142         "clear the first 5 bits"
   174         "clear the first 5 bits"
   143         buffer := buffer bitAnd:(1 bitShift:bits)-1.
   175         buffer := buffer bitAnd:(1 bitShift:bits)-1.
   144         charCount := charCount + 1.
   176         charCount := charCount + 1.
   145         bits := bits - 5.
   177         bits := bits - 5.
   146     ].
   178     ].
   147 
   179 
   148     "write 5 bits"
   180     "write 5 bits"
   149     stream nextPut:(Base32Mapping at:(buffer rightShift:bits)+1).
   181     stream nextPut:(mapping at:(buffer rightShift:bits)+1).
   150     "clear the first 5 bits"
   182     "clear the first 5 bits"
   151     buffer := buffer bitAnd:(1 bitShift:bits)-1.
   183     buffer := buffer bitAnd:(1 bitShift:bits)-1.
   152     charCount := charCount + 1.
   184     charCount := charCount + 1.
       
   185 
       
   186     "Modified: / 30-09-2018 / 15:32:16 / Claus Gittinger"
   153 ! !
   187 ! !
   154 
   188 
   155 !Base32Coder methodsFor:'misc'!
   189 !Base32Coder methodsFor:'misc'!
   156 
   190 
   157 flush
   191 flush
   173     ].
   207     ].
   174 
   208 
   175     shift := 5 - bits.
   209     shift := 5 - bits.
   176     buffer := buffer bitShift:shift.
   210     buffer := buffer bitShift:shift.
   177 
   211 
   178     stream nextPut:(Base32Mapping at:buffer+1).
   212     stream nextPut:(mapping at:buffer+1).
   179     bits := bits + 3.
   213     bits := bits + 3.
   180     [
   214     [
   181         "simulate adding 8 bits and removing 5 bits, until we get a multiple of 8"
   215         "simulate adding 8 bits and removing 5 bits, until we get a multiple of 8"
   182         stream nextPut:$=.
   216         stream nextPut:$=.
   183         bits := bits + 8 - 5.
   217         bits := bits + 8 - 5.
   184     ] doUntil:[bits \\ 8 == 0].
   218     ] doUntil:[bits \\ 8 == 0].
   185 
   219 
   186     buffer := bits := 0.
   220     buffer := bits := 0.
       
   221 
       
   222     "Modified: / 30-09-2018 / 15:32:08 / Claus Gittinger"
   187 ! !
   223 ! !
   188 
   224 
   189 !Base32Coder methodsFor:'private'!
   225 !Base32Coder methodsFor:'private'!
   190 
   226 
   191 fillBuffer
   227 fillBuffer
   200         [
   236         [
   201             b := stream next.
   237             b := stream next.
   202             b isNil ifTrue:[ "end of stream"
   238             b isNil ifTrue:[ "end of stream"
   203                 b := 32.     "simulate end-mark"
   239                 b := 32.     "simulate end-mark"
   204             ] ifFalse:[
   240             ] ifFalse:[
   205                 b := Base32ReverseMapping at:b codePoint ifAbsent:255.
   241                 b := reverseMapping at:b codePoint ifAbsent:255.
   206             ]
   242             ]
   207         ] doWhile:[b == 255].
   243         ] doWhile:[b == 255].
   208 
   244 
   209         b == 32 ifTrue:[
   245         b == 32 ifTrue:[
   210             "got $=, end of Base32 string has been reached.
   246             "got $=, end of Base32 string has been reached.
   221             bits := bits + 5.
   257             bits := bits + 5.
   222         ].
   258         ].
   223     ] doUntil:[bits == 40 or:[atEnd]].
   259     ] doUntil:[bits == 40 or:[atEnd]].
   224 
   260 
   225     buffer := tempBuffer.
   261     buffer := tempBuffer.
       
   262 
       
   263     "Modified: / 30-09-2018 / 15:43:20 / Claus Gittinger"
   226 ! !
   264 ! !
   227 
   265 
   228 !Base32Coder class methodsFor:'documentation'!
   266 !Base32Coder class methodsFor:'documentation'!
   229 
   267 
   230 version
   268 version