-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
base64.sh
90 lines (86 loc) · 3.74 KB
/
base64.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# shellcheck shell=sh disable=SC2016
##########################################################################
# Base64 encoder is released under the BSD Zero Clause License
# https://github.com/ko1nksm/sh-base64
##########################################################################
# base64encode
# $1: the 62nd and 63rd characters and optional padding (default: /=)
base64encode() {
set -- "${1:-" /="}" && set -- "${1%=}" "${1#??}"
set -- "$@" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
od -v -An -tx1 | LC_ALL=C tr -d ' \t\n' | {
LC_ALL=C fold -b -w120 # fold width must be a multiple of 6
} | {
# workaround for nawk: https://github.com/onetrueawk/awk/issues/38
[ "$2" = '=' ] && set -- "$1" '\075' "$3"
LC_ALL=C awk -v x="$3$1" -v p="$2" '
function dec2bin(n, w, r) {
for (r = ""; n > 0; n = int(n / 2)) r = (n % 2) r
return sprintf("%0" w "d", r)
}
BEGIN {
for (i = 0; i < 256; i ) b[sprintf("x", i)] = dec2bin(i, 8)
for (i in b) b[toupper(i)] = b[i]
# Process in pairs of two characters for better performance
for (i = 0; i < 64; i ) {
ik = dec2bin(i, 6); iv = substr(x, i 1, 1)
for (j = 0; j < 64; j ) c[ik dec2bin(j, 6)] = iv substr(x, j 1, 1)
}
}
{
len = length($0); pad = (3 - (len % 6 / 2)) % 3; bits = chars = ""
for (i = 0; i < pad; i ) { $0 = $0 "00"; len =2 }
for (i = 1; i <= len; i =2) bits = bits b[substr($0, i, 2)]
for (i = 1; i <= len * 4; i =12) chars = chars c[substr(bits, i, 12)]
if (pad > 0) chars = substr(chars, 1, length(chars) - pad)
while (pad--) chars = chars p
printf "%s", chars
}
END { print "" }
'
}
}
##########################################################################
# Base64 decoder is released under the BSD Zero Clause License
# https://github.com/ko1nksm/sh-base64
##########################################################################
# base64decode
# $1: the 62nd and 63rd characters and optional padding (default: /=)
base64decode() {
set -- "${1:-" /="}" && set -- "${1%=}" "${1#??}"
set -- "$@" "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
LC_ALL=C fold -b -w100 | { # fold width must be a multiple of 4
# workaround for nawk: https://github.com/onetrueawk/awk/issues/38
[ "$2" = '=' ] && set -- "$1" '\075' "$3"
LC_ALL=C awk -v x="$3$1" -v p="$2" '
function dec2bin(n, w, r) {
for (r = ""; n > 0; n = int(n / 2)) r = (n % 2) r
return sprintf("%0" w "d", r)
}
BEGIN {
# Process in pairs of two characters for better performance
for (i = 0; i < 64; i ) {
ik = substr(x, i 1, 1); iv = dec2bin(i, 6); b[ik] = b[ik p] = iv
for (j = 0; j < 64; j ) b[ik substr(x, j 1, 1)] = iv dec2bin(j, 6)
}
for (i = 1; i < 256; i ) c[dec2bin(i, 8)] = sprintf("%c", i)
c["00000000"] = "\\\\000"; c["00001001"] = "\\\\011" # NUL HT
c["00001010"] = "\\\\012"; c["00001011"] = "\\\\013" # LF VT
c["00001100"] = "\\\\014"; c["00001101"] = "\\\\015" # FF CR
c["00100000"] = "\\\\040"; c["00100010"] = "\\\\042" # SPC DQ
c["00100101"] = "\\\\045"; c["00100111"] = "\\\\047" # % SQ
c["01011100"] = "\\\\\\\\"
}
{
len = length($0); bits = chars = ""
for (i = 1; i <= len; i =2) bits = bits b[substr($0, i, 2)]
for (i = 1; i <= len * 6; i =8) chars = chars c[substr(bits, i, 8)]
print chars
}
'
} | (
for_mksh='[ ${KSH_VERSION: x} ] && alias printf="print -n";'
code='IFS=; printf -- "$*"' prog="${ZSH_ARGZERO:-"$0"}"
LC_ALL=C xargs -n 1000 -E '' sh -c "${for_mksh}${code}" "$prog"
)
}