merge current assockit from CVS, not yet enough
[shellsnippets/shellsnippets.git] / mksh / base64
1 # $MirOS: src/bin/mksh/dot.mkshrc,v 1.68 2011/11/25 23:58:04 tg Exp $
2 #-
3 # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
4 #       Thorsten Glaser <tg@mirbsd.org>
5 #
6 # Provided that these terms and disclaimer and all copyright notices
7 # are retained or reproduced in an accompanying document, permission
8 # is granted to deal in this work without restriction, including un-
9 # limited rights to use, publicly perform, distribute, sell, modify,
10 # merge, give away, or sublicence.
11 #
12 # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
13 # the utmost extent permitted by applicable law, neither express nor
14 # implied; without malicious intent or gross negligence. In no event
15 # may a licensor, author or contributor be held liable for indirect,
16 # direct, other damage, loss, or other issues arising in any way out
17 # of dealing in the work, even if advised of the possibility of such
18 # damage or existence of a defect, except proven that it results out
19 # of said person's immediate fault when using the work as intended.
20 #-
21 # RFC compliant base64 encoder and decoder
22
23 # NUL safe base64 decoder
24 function Lb64decode {
25         [[ -o utf8-mode ]]; local u=$?
26         set +U
27         local c s="$*" t=
28         [[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
29         local -i i=0 j=0 n=${#s} p=0 v x
30         local -i16 o
31
32         while (( i < n )); do
33                 c=${s:(i++):1}
34                 case $c {
35                 (=)     break ;;
36                 ([A-Z]) (( v = 1#$c - 65 )) ;;
37                 ([a-z]) (( v = 1#$c - 71 )) ;;
38                 ([0-9]) (( v = 1#$c + 4 )) ;;
39                 (+)     v=62 ;;
40                 (/)     v=63 ;;
41                 (*)     continue ;;
42                 }
43                 (( x = (x << 6) | v ))
44                 case $((p++)) {
45                 (0)     continue ;;
46                 (1)     (( o = (x >> 4) & 255 )) ;;
47                 (2)     (( o = (x >> 2) & 255 )) ;;
48                 (3)     (( o = x & 255 ))
49                         p=0
50                         ;;
51                 }
52                 t=$t\\x${o#16#}
53                 (( ++j & 4095 )) && continue
54                 print -n $t
55                 t=
56         done
57         print -n $t
58         (( u )) || set -U
59 }
60
61 set -A Lb64encode_code -- A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
62     a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /
63 if true; then
64 # not NUL safe base64 encoder
65 function Lb64encode {
66         [[ -o utf8-mode ]]; typeset u=$?
67         set +U
68         typeset c s="$*" t
69         [[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
70         typeset -i i=0 n=${#s} j v
71
72         while (( i < n )); do
73                 c=${s:(i++):1}
74                 (( v = 1#$c << 16 ))
75                 c=${s:(i++):1}
76                 (( j = ${#c} ? 1#$c : 0 ))
77                 (( v |= j << 8 ))
78                 c=${s:(i++):1}
79                 (( j = ${#c} ? 1#$c : 0 ))
80                 (( v |= j ))
81                 t=$t${Lb64encode_code[v >> 18]}${Lb64encode_code[v >> 12 & 63]}
82                 c=${Lb64encode_code[v >> 6 & 63]}
83                 if (( i <= n )); then
84                         t=$t$c${Lb64encode_code[v & 63]}
85                 elif (( i == n + 1 )); then
86                         t=$t$c=
87                 else
88                         t=$t==
89                 fi
90                 if (( ${#t} == 76 || i >= n )); then
91                         print $t
92                         t=
93                 fi
94         done
95         (( u )) || set -U
96 }
97 else
98 # NUL safe base64 encoder, needs mksh R40
99 function Lb64encode {
100         [[ -o utf8-mode ]]; local u=$?
101         set +U
102         local c s t
103         if (( $# )); then
104                 read -raN-1 s <<<"$*"
105                 unset s[${#s[*]}-1]
106         else
107                 read -raN-1 s
108         fi
109         local -i i=0 n=${#s[*]} j v
110
111         while (( i < n )); do
112                 (( v = s[i++] << 16 ))
113                 (( j = i < n ? s[i++] : 0 ))
114                 (( v |= j << 8 ))
115                 (( j = i < n ? s[i++] : 0 ))
116                 (( v |= j ))
117                 t+=${Lb64encode_code[v >> 18]}${Lb64encode_code[v >> 12 & 63]}
118                 c=${Lb64encode_code[v >> 6 & 63]}
119                 if (( i <= n )); then
120                         t+=$c${Lb64encode_code[v & 63]}
121                 elif (( i == n + 1 )); then
122                         t+=$c=
123                 else
124                         t+===
125                 fi
126                 if (( ${#t} == 76 || i >= n )); then
127                         print $t
128                         t=
129                 fi
130         done
131         (( u )) || set -U
132 }
133 fi