1 /* $NetBSD: put.c,v 1.12 2004/10/28 21:14:52 dsl Exp $ */
6 * Neil M. Haller <nmh@thumper.bellcore.com>
7 * Philip R. Karn <karn@chicago.qualcomm.com>
8 * John S. Walden <jsw@thumper.bellcore.com>
9 * Scott Chasin <chasin@crimelab.com>
11 * Dictionary lookup and extraction.
14 #include <sys/cdefs.h>
15 __RCSID("$NetBSD: put.c,v 1.12 2004/10/28 21:14:52 dsl Exp $");
21 #include <sys/types.h>
24 static unsigned int extract(char *s
, int start
, int length
);
25 static void standard(char *word
);
26 static void insert(char *s
, int x
, int start
, int length
);
27 static int wsrch(const char *w
, int low
, int high
);
29 /* Dictionary for integer-word translations */
2081 /* Encode 8 bytes in 'c' as a string of English words.
2082 * Returns a pointer to a static buffer
2084 char *btoe(char *engout
, const char *c
)
2086 char cp
[9]; /* add in room for the parity 2 bits */
2091 /* compute parity */
2092 for (p
= 0, i
= 0; i
< 64; i
+= 2)
2093 p
+= extract (cp
, i
, 2);
2095 cp
[8] = (char) p
<< 6;
2097 strncat (engout
, &Wp
[extract (cp
, 0, 11)][0], 4);
2098 strcat (engout
, " ");
2099 strncat (engout
, &Wp
[extract (cp
, 11, 11)][0], 4);
2100 strcat (engout
, " ");
2101 strncat (engout
, &Wp
[extract (cp
, 22, 11)][0], 4);
2102 strcat (engout
, " ");
2103 strncat (engout
, &Wp
[extract (cp
, 33, 11)][0], 4);
2104 strcat (engout
, " ");
2105 strncat (engout
, &Wp
[extract (cp
, 44, 11)][0], 4);
2106 strcat (engout
, " ");
2107 strncat (engout
, &Wp
[extract (cp
, 55, 11)][0], 4);
2110 printf ("engout is %s\n\r", engout
);
2115 /* convert English to binary
2116 * returns 1 OK - all good words and parity is OK
2117 * 0 word not in data base
2118 * -1 badly formed in put ie > 4 char word
2119 * -2 words OK but parity is wrong
2121 int etob(char *out
, const char *e
)
2124 int i
, p
, v
, l
, low
, high
;
2132 strncpy (input
, e
, sizeof (input
));
2133 memset (b
, 0, sizeof (b
));
2135 for (i
= 0, p
= 0; i
< 6; i
++, p
+= 11)
2137 if ((word
= strtok_r(i
== 0 ? input
: NULL
, " ", &last
)) == NULL
)
2155 if ((v
= wsrch (word
, low
, high
)) < 0)
2158 insert (b
, v
, p
, 11);
2161 /* now check the parity of what we got */
2162 for (p
= 0, i
= 0; i
< 64; i
+= 2)
2163 p
+= extract (b
, i
, 2);
2165 if ((p
& 3) != extract (b
, 64, 2))
2173 /* Display 8 bytes as a series of 16-bit hex digits */
2174 char *put8(char *out
, const char *s
)
2176 sprintf (out
, "%02X%02X %02X%02X %02X%02X %02X%02X",
2177 s
[0] & 0xff, s
[1] & 0xff, s
[2] & 0xff,
2178 s
[3] & 0xff, s
[4] & 0xff, s
[5] & 0xff,
2179 s
[6] & 0xff, s
[7] & 0xff);
2184 /* Encode 8 bytes in 'cp' as stream of ascii letters.
2185 * Provided as a possible alternative to btoe()
2187 char *btoc(char *cp
)
2190 static char out
[31];
2192 /* code out put by characters 6 bits each added to 0x21 (!) */
2193 for (i
= 0; i
<= 10; i
++)
2195 /* last one is only 4 bits not 6 */
2196 out
[i
] = '!' + extract (cp
, 6 * i
, i
>= 10 ? 4 : 6);
2204 /* Internal subroutines for word encoding/decoding */
2206 /* Dictionary binary search */
2207 static int wsrch(const char *w
, int low
, int high
)
2213 i
= (low
+ high
) / 2;
2214 if ((j
= strncmp (w
, Wp
[i
], 4)) == 0)
2215 return i
; /* Found it */
2216 if (high
== low
+ 1)
2218 /* Avoid effects of integer truncation in /2 */
2219 if (strncmp (w
, Wp
[high
], 4) == 0)
2225 return -1; /* I don't *think* this can happen... */
2227 high
= i
; /* Search lower half */
2229 low
= i
; /* Search upper half */
2233 static void insert (char *s
, int x
, int start
, int length
)
2241 assert (length
<= 11);
2242 assert (start
>= 0);
2243 assert (length
>= 0);
2244 assert (start
+ length
<= 66);
2246 shift
= ((8 - ((start
+ length
) % 8)) % 8);
2247 y
= (int) x
<< shift
;
2248 cl
= (y
>> 16) & 0xff;
2249 cc
= (y
>> 8) & 0xff;
2251 if (shift
+ length
> 16)
2254 s
[start
/ 8 + 1] |= cc
;
2255 s
[start
/ 8 + 2] |= cr
;
2257 else if (shift
+ length
> 8)
2260 s
[start
/ 8 + 1] |= cr
;
2268 static void standard(char *word
)
2272 if (!isascii (*word
))
2274 if (islower ((unsigned char)*word
))
2275 *word
= toupper ((unsigned char)*word
);
2286 /* Extract 'length' bits from the char array 's' starting with bit 'start' */
2287 static unsigned int extract(char *s
, int start
, int length
)
2294 assert (length
<= 11);
2295 assert (start
>= 0);
2296 assert (length
>= 0);
2297 assert (start
+ length
<= 66);
2300 cc
= s
[start
/ 8 + 1];
2301 cr
= s
[start
/ 8 + 2];
2302 x
= ((int) (cl
<< 8 | cc
) << 8 | cr
);
2303 x
= x
>> (24 - (length
+ (start
% 8)));
2304 x
= (x
& (0xffff >> (16 - length
)));