Any of you remember those Cue Cats from several years back? If not, then this code doesn't do you any good. Otherwise, whip out that cat and start using it again!
Unless your cue cat is modified, the returned string includes a unique serial number along with the UPC code. The string, however, is encrypted. If you don't feel like sticking a piece of wire into your cue cat's circuit board with +5v to disable the serial and encryption, you can use this code to decrypt it.
I did take a look at some code created by P. Taylor Goetz to notice that, before doing the decoding and xoring, the case of each letter had to be flipped first.
Global device_id as string
Global upc_type as string
Global upc_code as string
repeat
set cursor 0,0
rem get the string from the cue cat
input "> ",code$
rem decode the string
CCDecoder(code$)
cls
rem display values
set cursor 0,24
print "Device ID: ",device_id
print "UPC Type: ",upc_type
print "UPC Code: ",upc_code
until code$ = ""
rem takes a string read from a cuecat
rem and stores the decoded result in
rem the 3 global variables
function CCDecoder(code as string)
temp as string
param = 1
for i = 2 to len(code)
if mid$(code,i) = "."
select param
case 1 : device_id = temp : inc param : temp="" : endcase
case 2 : upc_type = temp : inc param : temp="" : endcase
case 3 : upc_code = temp : inc param : temp="" : endcase
endselect
else
temp = temp + mid$(code,i)
endif
next i
device_id = xor67$(decode64$(flip$(device_id)))
upc_type = xor67$(decode64$(flip$(upc_type)))
upc_code = xor67$(decode64$(flip$(upc_code)))
endfunction
rem flips the case of each character
rem AbC becomes aBc
function flip$(s as string)
t as string
for i = 1 to len(s)
c$ = mid$(s,i)
if asc(c$) > 96
t = t+upper$(c$)
else
t = t+lower$(c$)
endif
next i
endfunction t
rem xor's a string by 67
rem DC's weak encryption scheme on the cuecat
function xor67$(code as string)
t as string
for i = 1 to len(code)
t = t + chr$(asc(mid$(code,i))~~67)
next i
endfunction t
rem Decodes a string to base64
rem returns a decoded string
function decode64$(decode as string)
b1 as byte
b2 as byte
b3 as byte
value$ = ""
temp$ = ""
for j = 1 to len(decode)
if isBase64(mid$(decode,j)) then temp$ = temp$ + mid$(decode,j)
next j
if len(temp$) = 0 then exitfunction value$
for i = 1 to len(temp$) step 4
c1$ = "A"
c2$ = "A"
c3$ = "A"
c4$ = "A"
c1$ = mid$(temp$, i)
if i+1 <= len(temp$) then c2$ = mid$(temp$,i+1)
if i+2 <= len(temp$) then c3$ = mid$(temp$,i+2)
if i+3 <= len(temp$) then c4$ = mid$(temp$,i+3)
b1 as byte
b2 as byte
b3 as byte
b4 as byte
b1 = decodeChar(c1$)
b2 = decodeChar(c2$)
b3 = decodeChar(c3$)
b4 = decodeChar(c4$)
value$ = value$ + chr$(b1<<2 || b2>>4)
if c3$ <> "=" then value$ = value$ + chr$(((b2&&0xf)<<4) || (b3>>2))
if c4$ <> "=" then value$ = value$ + chr$(((b3&&0x3)<<6) || b4)
next i
endfunction value$
rem private helper function
rem character as input
rem returns byte value of decoded char
function decodeChar(c as string)
if c >= "A" and c <= "Z"
v = asc(c)-asc("A")
exitfunction v
endif
if c >= "a" and c <= "z"
v = asc(c)-asc("a")+26
exitfunction v
endif
if c >= "0" and c <= "9"
v = asc(c)-asc("0")+52
exitfunction v
endif
if c = "+" then exitfunction 62
endfunction 63
rem private helper function
rem checks if the character is a
rem valid base64 character
rem returns true or false
function isBase64(c as string)
if c >= "A" and c <= "Z" then exitfunction 1
if c >= "a" and c <= "z" then exitfunction 1
if c >= "0" and c <= "9" then exitfunction 1
if c = "+" then exitfunction 1
if c = "/" then exitfunction 1
if c = "=" then exitfunction 1
endfunction 0
"Using Unix is the computing equivalent of listening only to music by David Cassidy" - Rob Pike