BASE64

 投稿者:しばっち  投稿日:2020年10月 3日(土)19時40分49秒
  文字列をBASE64エンコード、デコードします。
BASE64では、3バイト24bitずつ取り出してそれを6bitずつ4つに分けます。
6bitつまり2^6で64進文字列に変換します。
文字数が3倍数でない時は"="で埋めます。
3バイトを4文字(バイト)に変換するので増大率は4/3倍になります。
デコードでは4文字ずつ取り出し3バイト24bitの文字列に変換します。

この変換を施すと文字コード(0~255)は全て表示可能文字(印刷可能文字)
となります。

エンコードに使用する文字種を変えた亜種があるようです。
https://ja.wikipedia.org/wiki/Base64


ちなみにBASE16では1バイト8bitを4bitずつ2つに分けます。
4bitつまり2^4で16進文字列に変換します。
これはBSTR$(n,16) BVAL(n$,16)で簡単に変換できます。
1バイトを2文字に変換するので増大率は2倍になります。


BASE64より更に増大率を抑えたBASE85というのもあるようです。
https://ja.wikipedia.org/wiki/Ascii85


OPTION CHARACTER BYTE
DO
   READ IF MISSING THEN EXIT DO:A$
   LET S$=ENCODEBASE64$(A$)
   PRINT "原文  :";A$
   PRINT "ENCODE:";S$
   PRINT "DECODE:";DECODEBASE64$(S$)
   PRINT
LOOP
DATA A
DATA AB
DATA ABC
DATA ABCD
DATA ABCDE
DATA ABCDEFGHIJKLMNOPQRSTUVWXYZ
DATA 0123456789
DATA 十進BASIC
END

EXTERNAL  FUNCTION ENCODEBASE64$(A$)
OPTION CHARACTER BYTE
LET S$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
LET L=MOD(LEN(A$),3)
FOR I=0 TO INT(LEN(A$)/3)-1
   LET D$=A$(3*I+1:3*I+3)
   LET N=ORD(D$(1:1))*256^2+ORD(D$(2:2))*256+ORD(D$(3:3))
   LET N1=MOD(INT(N/64^3),64)+1
   LET N2=MOD(INT(N/64^2),64)+1
   LET N3=MOD(INT(N/64),64)+1
   LET N4=MOD(N,64)+1
   LET ENC$=ENC$&S$(N1:N1)&S$(N2:N2)&S$(N3:N3)&S$(N4:N4)
NEXT I
LET D$=A$(3*I+1:LEN(A$))
SELECT CASE L
CASE 0
CASE 2
!'2byte 16bit 123456  781234  567800  4倍して6bitずつ*3つ
   LET N=ORD(D$(1:1))*256+ORD(D$(2:2))
   LET N=N*4
   LET N1=MOD(INT(N/64^2),64)+1
   LET N2=MOD(INT(N/64),64)+1
   LET N3=MOD(N,64)+1
   LET ENC$=ENC$&S$(N1:N1)&S$(N2:N2)&S$(N3:N3)&"="
CASE 1
!'1byte 8bit 123456  780000  16倍して6bitずつ*2つ
   LET N=ORD(D$)
   LET N=N*16
   LET N1=MOD(INT(N/64),64)+1
   LET N2=MOD(N,64)+1
   LET ENC$=ENC$&S$(N1:N1)&S$(N2:N2)&"=="
END SELECT
LET ENCODEBASE64$=ENC$
END FUNCTION

EXTERNAL  FUNCTION DECODEBASE64$(M$)
OPTION CHARACTER BYTE
LET A$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
FOR I=0 TO LEN(M$)/4-1
   LET L$=M$(4*I+1:4*I+4)
   IF RIGHT$(L$,2)="==" THEN
      LET N1=POS(A$,L$(1:1))-1
      LET N2=POS(A$,L$(2:2))-1
      LET N=N1*64+N2
      LET N=N/16
      LET DEC$=DEC$&CHR$(MOD(N,256))
   ELSEIF RIGHT$(L$,1)="=" THEN
      LET N1=POS(A$,L$(1:1))-1
      LET N2=POS(A$,L$(2:2))-1
      LET N3=POS(A$,L$(3:3))-1
      LET N=N1*64^2+N2*64+N3
      LET N=N/4
      LET DEC$=DEC$&CHR$(MOD(INT(N/256),256))&CHR$(MOD(N,256))
   ELSE
      LET N1=POS(A$,L$(1:1))-1
      LET N2=POS(A$,L$(2:2))-1
      LET N3=POS(A$,L$(3:3))-1
      LET N4=POS(A$,L$(4:4))-1
      LET N=N1*64^3+N2*64^2+N3*64+N4
      LET DEC$=DEC$&CHR$(MOD(INT(N/256^2),256))&CHR$(MOD(INT(N/256),256))&CHR$(MOD(N,256))
   END IF
NEXT I
LET DECODEBASE64$=DEC$
END FUNCTION
 

戻る