--- /dev/null
+# base64decode.awk
+# Bitwise AND between 2 variables - var AND x
+function _and(var, x, l_res, l_i) {
+l_res=0;
+
+for (l_i=0; l_i < 8; l_i++){
+ if (var%2 == 1 && x%2 == 1) l_res=l_res/2 + 128;
+ else l_res/=2;
+ var=int(var/2);
+ x=int(x/2);
+}
+return l_res;
+}
+
+# Rotate bytevalue left x times
+function _lshift(var, x)
+{
+while(x > 0){
+ var*=2;
+ x--;
+}
+return var;
+}
+
+# Rotate bytevalue right x times
+function _rshift(var, x)
+{
+while(x > 0){
+ var=int(var/2);
+ x--;
+}
+return var;
+}
+
+# This is the main program
+function base64decode(str) {
+# NB 01.12.17 cmd="echo "str" | base64 -d"
+# NB 01.12.17 cmd | getline str
+# NB 01.12.17 close(cmd)
+# NB 01.12.17 return str
+# NB 01.12.17 print ">"str
+
+ BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+
+ result = ""
+
+ while (length(str) > 0){
+
+ # Specify byte values
+ base1 = substr(str, 1, 1)
+ base2 = substr(str, 2, 1)
+ base3 = substr(str, 3, 1)
+ base4 = substr(str, 4, 1)
+
+ # Now find numerical position in BASE64 string
+ byte1 = index(BASE64, base1) - 1
+ if (byte1 < 0) byte1 = 0
+ byte2 = index(BASE64, base2) - 1
+ if (byte2 < 0) byte2 = 0
+ byte3 = index(BASE64, base3) - 1
+ if (byte3 < 0) byte3 = 0
+ byte4 = index(BASE64, base4) - 1
+ if (byte4 < 0) byte4 = 0
+
+ # Reconstruct ASCII string
+ result = result sprintf( "%c", _lshift(_and(byte1, 63), 2) + _rshift(_and(byte2, 48), 4) )
+ result = result sprintf( "%c", _lshift(_and(byte2, 15), 4) + _rshift(_and(byte3, 60), 2) )
+
+# NB 01.12.17 command substitution: ignored null byte in input
+# NB 01.12.17 result = result sprintf( "%c", _lshift(_and(byte3, 3), 6) + byte4 )
+ val = _lshift(_and(byte3, 3), 6) + byte4
+ if (val) result = result sprintf( "%c", val )
+
+ # Decrease incoming string with 4
+ str = substr(str, 5)
+
+ }
+
+ return result
+}