A :CueCat is a barcode scanner that plugs into a PC's keyboard port. One of the best things about a :CueCat is that you can get one absolutely free from your friendly neighborhood Radio Shack.
After you've plugged it in and done a few practice swipes, you should see something like this:
q.C3nZC3nZC3nWDNzYDxf2CNnY.fHmc.C3DWC3nZCNjXD3nW.
Looks like a lot of useless gibberish, but notice that there are four
fields separated by periods. The first field "q" is a header that always
contains Alt+F10. The second field contains the serial number of your
particular scanner. The next field identifies the type of barcode
detected, and the last field is the numeric value of the barcode.
Here's how to unscramble the characters:
1. Get a 4-character sequence.
2. Look up each character's position in this table:
0: abcdefghijklmnop
16: qrstuvwxyzABCDEF
32: GHIJKLMNOPQRSTUV
48: WXYZ0123456789+-
3. Convert the position number to binary.
4. Regroup the binary digits to form three 8-bit values.
5. Exclusive-or 01000011 with each of the three values.
6. Convert the binary to ASCII.
For example, the last field above begins with "C3DW":
1. C 3 D W
2. 28 55 29 48
3. 011100 110111 011101 110000
4. 01110011 01110111 01110000
5. 01000011 01000011 01000011
00110000 00110100 00110011
6. 0 4 3
The complete decoding reveals the Universal Product Code of my favorite cereal:
000000003551625101
UPA
043000112403
\CUECAT.XPL 19-MAY-2001
\:CueCat Decoder
\32-bit XPL (XPLP) must be used because of the 24-bit value in the Decode proc.
include \cxpl\codesi;
char LineBuf, \line of text read in by :CueCat
CodeTbl; \decoder table
int Ch, J, Field;
def CR=$0D, Esc=$1B;\ASCII control characters
func GetIndex(Ch); \Return index to Ch in CodeTbl, 0 if none
int Ch;
int I;
begin
for I:= 0, 63 do \for all the characters in CodeTbl...
if Ch = CodeTbl(I) then return I;
return 0; \illegal character
end; \GetIndex
proc Decode(S4);
\Convert a 4-character string S4 into 3 ASCII characters and display them
char S4; \address of 4-character string
int S3, I;
char AS3; \address of S3 (to access the bytes)
begin
S3:= 0;
for I:= 0, 3 do
S3:= S3<<6 + GetIndex(S4(I));
AS3:= addr S3;
for I:= 0, 2 do Chout(0, AS3(2-I) | $43);
end; \Decode
begin \Main
LineBuf:= Reserve(100);
Text(0, ":CueCat Decoder
Esc = exit
");
CodeTbl:= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+- ";
loop begin
for J:= 0, 99 do LineBuf(J):= ^.; \(required for UPE barcodes)
Crlf(0);
J:= 0;
repeat Ch:= Chin(1); \read character from :CueCat
if Ch = Esc then quit; \Esc aborts program (manual keystroke)
Chout(0, Ch); \echo character to display
LineBuf(J):= Ch; \store character into line buffer
J:= J + 1;
until Ch = CR; \:CueCat line terminator
Crlf(0);
J:= 3; \skip Alt+F10's scan code and skip "."
for Field:= 0, 2 do
begin
repeat Decode(addr LineBuf(J));
J:= J + 4; \next 4-char string
until LineBuf(J) = ^.; \field separator
J:= J + 1; \skip "."
Crlf(0);
end;
end;
end; \Main
:CueCat is a trademark of Digital:Convergence Corporation
Last updated: 13-Mar-2004