pohlcode.awk - annna - Annna the nice friendly bot. HTML git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/annna/ DIR Log DIR Files DIR Refs DIR Tags DIR README --- pohlcode.awk (6389B) --- 1 #!/usr/bin/awk -f 2 # pohlcode.awk version 3 by Ben Collver 3 # 4 # Implement spoken representation of binary numbers described in 5 # On Binary Digits And Human Habits by Frederik Pohl, 1962. 6 # 7 # Dual license: WTFPL and Public Domain 8 # 9 # Pohl encode string from decimal number: 10 # awk -f pohlcode.awk 31337 11 # 12 # Decode decimal number from Pohl encoded string: 13 # awk -f pohlcode.awk tee two group totter-poot totter-poot 14 15 # initialize tables used to convert between bases and encodings 16 17 function init( hl, hu, i) { 18 split("pohl poot pahtah pod too tot dye tee", second, " ") 19 split("ohly ooty ahtah oddy too totter dye teeter", first, " ") 20 split("000 001 010 011 100 101 110 111", trip, " ") 21 split("zero one two three four five six seven eight nine", eng, " ") 22 split("0 1 2 3 4 5 6 7 8 9 A B C D E F", hex, " ") 23 split("0000 0001 0010 0011 0100 0101 0110 0111 " \ 24 "1000 1001 1010 1011 1100 1101 1110 1111", bin, " ") 25 26 # bin/dec/hex conversion tables 27 for (i in hex) { 28 hu = hex[i] 29 hl = tolower(hu) 30 h2b[hl] = h2b[hu] = bin[i] 31 h2d[hl] = h2d[hu] = i - 1 32 b2h[bin[i]] = hu 33 } 34 35 # english digit conversion tables 36 for (i in eng) { 37 d2e[i - 1] = eng[i] 38 e2d[eng[i]] = i - 1 39 } 40 41 # Pohl code binary triplet conversion tables 42 for (i in trip) { 43 f2p[trip[i]] = first[i] 44 s2p[trip[i]] = second[i] 45 p2f[first[i]] = trip[i] 46 p2s[second[i]] = trip[i] 47 } 48 49 return 50 } 51 52 function bin2dec(str, dec, hex) { 53 hex = bin2hex(str) 54 dec = hex2dec(hex) 55 return dec 56 } 57 58 function bin2hex(str, chunk, n, i, hex, pad, rem) { 59 str = zpad4(str) 60 n = length(str) 61 for (i = 1; i <= n; i += 4) { 62 chunk = zpad4(substr(str, i, 4)) 63 hex = hex b2h[chunk] 64 } 65 return hex 66 } 67 68 function bin2pohl(bin, bbuf, groups, p, parts, retval, val) { 69 groups = int(length(bin) / 6) 70 if (groups > 9) { 71 print "Error: groups out of bounds: " groups 72 exit 1 73 } 74 p = 0 75 bbuf = zpad6(bin) 76 if (length(bbuf) > length(bin)) { 77 val = substr(bbuf, 1, 6) 78 sub(/^000/, "", val) 79 bbuf = substr(bbuf, 7) 80 p++ 81 parts[p] = pohlencode(val) 82 } 83 if (groups > 0) { 84 p++ 85 parts[p] = d2e[groups] " group" 86 } 87 for (i = 1; i <= groups; i++) { 88 val = substr(bbuf, 1, 6) 89 bbuf = substr(bbuf, 7) 90 p++ 91 parts[p] = pohlencode(val) 92 } 93 retval = "" 94 for (i = 1; i <= p; i++) { 95 if (length(retval) == 0) { 96 retval = parts[i] 97 } else { 98 retval = retval " " parts[i] 99 100 } 101 } 102 return retval 103 } 104 105 function dec2bin(dec, hex, bin) { 106 hex = sprintf("%x\n", dec) 107 bin = hex2bin(hex) 108 return bin 109 } 110 111 function hex2bin(hex, n, i, bin) { 112 n = length(hex) 113 for (i = 1; i <= n; i++) { 114 bin = bin h2b[substr(hex, i, 1)] 115 } 116 sub(/^0+/, "", bin) 117 if (length(bin) == 0) { 118 bin = "0" 119 } 120 return bin 121 } 122 123 function hex2dec(val, out, i, n) { 124 if (val ~ /^0x/) { 125 val = substr(val, 3) 126 } 127 n = length(val) 128 for (i = 1; i <= n; i++) { 129 out = (out * 16) + h2d[substr(val, i, 1)] 130 } 131 #return sprintf("%.0f", out) 132 return out 133 } 134 135 function pohl2bin(str, bbuf, eng, groups, i, prefix, result, wnum, \ 136 words) 137 { 138 bbuf = "" 139 groups = 1 140 result = match(str, /.* group /) 141 if (result > 0) { 142 prefix = substr(str, 1, RLENGTH) 143 str = substr(str, RLENGTH + 1) 144 wnum = split(prefix, words, " ") 145 if (wnum == 2) { 146 eng = words[1] 147 } else if (wnum == 3) { 148 eng = words[2] 149 bbuf = pohldecode(words[1]) 150 sub(/^0*/, "", bbuf) 151 } else { 152 print "Bad Pohl code prefix: " prefix 153 exit 1 154 } 155 if (eng in e2d) { 156 groups = e2d[eng] 157 } else { 158 print "Invalid number of groups: " eng 159 exit 1 160 } 161 } 162 wnum = split(str, words, " ") 163 if (wnum != groups) { 164 print "Expected " groups " group(s) but got: " wnum 165 exit 1 166 } 167 for (i = 1; i <= wnum ; i++) { 168 bbuf = bbuf pohldecode(words[i]) 169 } 170 return bbuf 171 } 172 173 # decode pohl-encoded 6-bit word 174 175 function pohldecode(word, parts, pnum, retval) { 176 pnum = split(word, parts, "-") 177 if (pnum == 2 && parts[1] in p2f && parts[2] in p2s) { 178 retval = p2f[parts[1]] p2s[parts[2]] 179 } else if (pnum == 1 && parts[1] in p2s) { 180 retval = "000" p2s[parts[1]] 181 } else { 182 print "Invalid pohl code word: " word 183 exit 1 184 } 185 return retval 186 } 187 188 # pohl encode 6-bit word 189 190 function pohlencode(digits, retval, triplet1, triplet2) { 191 if (length(digits) == 3) { 192 retval = s2p[digits] 193 } else { 194 triplet1 = substr(digits, 1, 3) 195 triplet2 = substr(digits, 4, 6) 196 retval = f2p[triplet1] "-" s2p[triplet2] 197 } 198 return retval 199 } 200 201 # zero pad number until length is a multiple of 4 digits 202 203 function zpad4(str, pad, rem) { 204 rem = length(str) % 4 205 if (rem > 0) { 206 pad = substr("0000", 1, 4 - rem) 207 str = pad str 208 } 209 return str 210 } 211 212 # zero pad number until length is a multiple of 6 digits 213 214 function zpad6(str, pad, rem) { 215 rem = length(str) % 6 216 if (rem > 0) { 217 pad = substr("000000", 1, 6 - rem) 218 str = pad str 219 } 220 return str 221 } 222 223 function main( i, result, val) { 224 for (i = 1; i < ARGC; i++) { 225 if (length(val) == 0) { 226 val = ARGV[i] 227 } else { 228 val = val " " ARGV[i] 229 } 230 } 231 if (length(val) == 0) { 232 print "Usage: pohlcode.awk [code|number|test]" 233 print "" 234 print "[code]: Converts Pohl code to decimal." 235 print "[number]: Converts decimal to Pohl code." 236 print "test: Print test output." 237 exit 1 238 } 239 sub(/\n$/, "", val) 240 init() 241 if (val == "test") { 242 test() 243 } else if (val ~ /^[0-9][0-9]*$/) { 244 result = bin2pohl(dec2bin(val)) 245 } else { 246 result = bin2dec(pohl2bin(val)) 247 } 248 print result 249 return 250 } 251 252 function test( code, i, j) { 253 return 254 for (i = 0; i < 1024; i++) { 255 code = bin2pohl(dec2bin(i)) 256 j = bin2dec(pohl2bin(code)) 257 printf "%d\t%s\t%d\n", i, code, j 258 } 259 return 260 } 261 262 BEGIN { 263 main() 264 exit 0 265 }