pohlcode.awk - annna - Annna the nice friendly bot.
(HTM) 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 }