# -*- coding: utf-8 mode: awk -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 function base64__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 base64__lshift(var, x) { while(x > 0) { var *= 2; x--; } return var; } # Rotate bytevalue right x times function base64__rshift(var, x) { while(x > 0) { var = int(var/2); x--; } return var; } BEGIN { BASE64__BYTES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; } function b64decode(src, result, base1, base2, base3, base4) { result = ""; while (length(src) > 0) { # Specify byte values base1 = substr(src, 1, 1); base2 = substr(src, 2, 1); base3 = substr(src, 3, 1); if (base3 == "") base3 = "="; base4 = substr(src, 4, 1); if (base4 == "") base4 = "="; # Now find numerical position in BASE64 string byte1 = index(BASE64__BYTES, base1) - 1; if (byte1 < 0) byte1 = 0; byte2 = index(BASE64__BYTES, base2) - 1; if (byte2 < 0) byte2 = 0; byte3 = index(BASE64__BYTES, base3) - 1; if (byte3 < 0) byte3 = 0; byte4 = index(BASE64__BYTES, base4) - 1; if (byte4 < 0) byte4 = 0; # Reconstruct ASCII string result = result sprintf( "%c", base64__lshift(base64__and(byte1, 63), 2) + base64__rshift(base64__and(byte2, 48), 4) ); if (base3 != "=") result = result sprintf( "%c", base64__lshift(base64__and(byte2, 15), 4) + base64__rshift(base64__and(byte3, 60), 2) ); if (base4 != "=") result = result sprintf( "%c", base64__lshift(base64__and(byte3, 3), 6) + byte4 ); # Decrease incoming string with 4 src = substr(src, 5); } return result; }