-
Notifications
You must be signed in to change notification settings - Fork 63
/
yf_base32_decode.function
70 lines (70 loc) · 3.71 KB
/
yf_base32_decode.function
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
#! /bin/true
# vi: set tabstop=4 syntax=sh : # colorize it in 'vi' and use shorter tabstops
# SPDX-License-Identifier: GPL-2.0-or-later
#######################################################################################
# #
# base32_decode - convert STDIN from base32 format (AVMs character set) to the binary #
# content #
# #
# parameters: #
# none #
# #
# stdin: #
# the content to decode, size has to be a multiple of 8 on each line and a newline #
# character is needed at the end (otherwise the 'read' command will fail), even if #
# the encoding function does not add one (it doesn't split its output into lines) #
# #
# stdout: #
# the decoded data #
# #
# return code: #
# 0 - stdout value is valid #
# 1 - error occured, input data is invalid #
# #
#######################################################################################
# #
# U: sed printf expr dd #
# W: - #
# I: - #
# F: yf_substring yf_index #
# K: avm encryption fritzbox #
# #
#######################################################################################
yf_base32_decode()
(
[ -t 0 ] && return 1
rc=1 # preset, if no newline is present on STDIN, our 'read' will signal instant EOF
while read line; do
rc=0
! [ -z "$(expr \( "$line" : "\([^A-Z1-6\r]\)" \) )" ] && return 1
line=$(printf "%s" $line | sed -e "s|\r||g")
[ $(( ${#line} % 8 )) -gt 0 ] && return 1
i=0
f=0
while [ $i -lt ${#line} ]; do
part=$(printf "%s" $(yf_substring "$line" $i 8) | sed -e "s|.|& |g")
i=$(( i + 8 ))
v=0
j=0
for c in $part; do
v=$(( ( v * 32 ) + $(yf_index "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456" $c) - 1 ))
j=$(( j + 1 ))
[ $(( j % 4 )) -ne 0 ] && continue
# process 16 and 24 bits in two separate steps, this avoids
# problems with 32-bit-limited arithmetics
r=$(( j % 8 ))
o=$(( v >> r ))
s=$(( 24 - ( r * 2 ) ))
v=$(( v & ( 0x00FFFFFF >> ( r * 5 ) ) ))
while [ $s -gt 0 ]; do
s=$(( s - 8 ))
d=$(( ( o >> s ) & 255 ))
[ $d -eq 0 ] \
&& dd if=/dev/zero bs=1 count=1 2>/dev/null \
|| printf "%b" "\0$(( d >> 6 ))$(( ( d >> 3 ) & 7 ))$(( d & 7 ))"
done
done
done
done
return $rc
)