For years and years I tried to decode the Showview™-Codes (the German version of VCRPlus™) and finally found the informations of Ken Shirriff and Curt Welch on the internet. Those seemed not only to be the result of hard work and to show the correct algorithm (of course without the still to be broken 7th and 8th digit) but a little on the hard to understand side. Some ideas about the 7th and 8th digit (in German language) you'll find here.
I always felt that this algorithm was too complicated (and timeconsuming) for the small processors and the amount of RAM in the vcr's.
Then I was really glad to find the informations of Herbert Fichtner (also in German) for Showview™ (The differences between Showview™ and VCRPlus™ are - as far as known -in the underlying bit orders and the time/duration tables). He took a different approach (after reading Shirriff and Welch) to compute the code and described it in mathematical terms. His approach was simpler in the way of achieving the results but not so easy to understand even for a mathematic.
As a programmer and having studied mathematics at
the university I first undertook the task of understanding
Fichtner's paper. With a little help of the original papers of
Shirriff and Welch I finally was able to succeed.
In the process I not only thought about the necessity of having a
whole example for better understanding but even was able to find
some simplifications to make the whole algorithm easier to
understand, to follow and to program. In my opinion this
minimalistic approach would very much be in the reach of those
aforementioned small processors.
To my own surprise the simple algorithm made it really easy (much easier than the original one) to reverse the process and do the encoding as well.
I then decided to publish my results on the
internet too and to include a complete example
for better understanding.
I commented briefly on the differences.
For those of you not so mathematical inclined are here some
useful informations:
If you read "modulo 10" it's the same as "truncated"
in the original paper. It tells you to only use the last digit of
the result.
Addition: 3 + 7 = 0, 9 + 8 = 7, 1
+ 1 = (still) 2.
Subtraction: 3 - 0 = 3 (surprise!), 4 - 5 = 9, 3 - 6 = 7.
Multiplication: 9 * 9 = 1, 1 * 1 = 1, 3 * 7 = 1, 5 * 4 = 0, 6 * 9
= 4.
After you (kind of)
understood the document above you might want to try the |
If the code number has 9 digits and the first digit is bigger than 4: Bad luck! Up to now we only know that then a socalled channel bit is set to 1 and you have to subtract 5 from the first digit before you work with the resulting code number. There is (up to now) no information what to do with the channel bit!
If the code number has 9 digits (happens a lot in Germany and seems not to happen in the states?) separate the first digit (if it has a value between 1 and 4 otherwise it's yet still to be broken) and write it down somewhere. If then there are some leading zeroes throw them away and take the rest as code number and work with it.
If the code number (from the beginning on or after removing the first digit and maybe one leading zero) has 7 or 8 digits: Bad luck! Up to now those numbers cannot be decoded yet. But we're working on it!
Lately an anonymous C-program has shown up on the internet (http://www.cs.cmu.edu/~dst/VCRPlus+, formerly under www.cryptome.org) that seems to be able to handle 7+8. I will try to understand, maybe simplify and then publish it here.
Code number 305-682-975, separate 1. digit "3", throw away the leading zero, the code number is now 5-682-975. It has 7 digits and thus not yet decodable. DESPARE!
Code number 300-061-798, separate 1. digit "3", throw away the leading zeroes, the code number is now 61-798. We now have 5 digits and may proceed.
The original number is kind of encrypted. The length has to be preserved at all means. If the new number has one or more leading zeroes the process has to be done again with this new number. With up to 6 digits the process has to be done at most 6 times!
The last digit stays the same all
the time! So the last number of the new number is the last number
of the code.
Add (modulo 10) the second digit from the right
of the code to the rightmost
digit of the new number to get the second
digit from the right of the new number.
Add (modulo 10) the third digit from the right
of the code to the second digit
from the right of the new number digit to get
the third digit from the right of the new number.
Do so for all the other digits!
Repeat this process two more times!
Code 61-798
5. digit new number = | 8 | 8 |
4. digit = | 9+8 = | 7 |
3. digit = | 7+7 = | 4 |
2. digit = | 1+4 = | 5 |
1. digit = | 6+5 = | 1 |
new number = | 15-478 |
Intermediate number 15-478
5. digit new number = | 8 | 8 |
4. digit = | 7+8 = | 5 |
3. digit = | 4+5 = | 9 |
2. digit = | 5+9 = | 4 |
1. digit = | 1+4 = | 5 |
new number = | 54-958 |
Intermediate number 54-958
5. digit new number = | 8 | 8 |
4. digit = | 5+8 = | 3 |
3. digit = | 9+3 = | 2 |
2. digit = | 4+2 = | 6 |
1. digit = | 5+6 = | 1 |
new number = | 16-238 |
Step 3 (no difference/improvement here):
The rightmost three digits will be separated and 1 will be subtracted. The result I call "Bottom", the remaining digits "Top".
Code number 16-238
Bottom = 238 - 1 = 237
Top = 16
Step 4 (no difference either):
Divide Bottom by 32 (normal division), add 1 (normal addition) to the quotient to yield the day. The remainder will be called Rem
Bottom = 237
Day = 237 / 32 = 7 + 1 = 8
Rem = remainder of 237/32 = 13
Step 5:
The vcr has a
built-in clock that delivers the actual day, month and year. Month
and year are not included in the code, although they are needed
for the decoding! If your vcr clock is wrong so will be your
programming!
If the day of the code is less than the actual day than it is
assumed that the code is meant for the next month.
Computing two new numbers "Newtop" and "Offset" from "Top" (step 3).
Add all the digits of Top giving Offset.
The two-digit year
modulo 16 (plus 1) tells us how often to do the following process.
Add the first digit of Top and
the last digit of the day to
get the first digit of the new
number (modulo 10).
Add the second digit of Top to
the first digit of the new
number giving the second digit of the new
number (modulo 10).
Do so for the other digits of Top.
Add the last digit of the new
number (normal) to Offset.
The final result will be called Newtop.
If Newtop has fewer digits than Top repeat (with Newtop as base)
until the number of digits are equal.
Offset has to be taken modulo 32!
It is assumed that
your vcr's date is set somewhere between 05/01 and 05/07/2001!
Top = 16, day = 8. year = 01 (only last two digits!)
Offset = (addition of digits of Top) 1 + 6 = 7
Year 01 modulo 16 = 1, we have to do it twice!
First digit new number = 1 + 8 (day!) = 9
Second digit new number = 6 + 9 = 5
Offset = 7+ 5 = 12
New number = 95 (if this has been the last pass
of the process this number will be Newtop!)
First digit new number = 9 + 8 (day) = 7
Second to last digit new number = 5 + 7 = 2
Offset = 12+ 2 = 14
New number = 72 (if this has been the last pass
of the process this number will be Newtop!)
(thus Newtop = 72)
Step 6 (no difference):
Computing a new number Top2 = (Rem + Day * (Month+1) + Offset) modulo 32
Rem 13, Day = 8,
Month = 5, Offset = 14
Top2 = (13 + 8 * (5 + 1) + 14) = 75 (modulo 32) = 11
Step 7 (no difference):
Convert Newtop and Top2 to binary. The t-bits are for time and duration, the c-bits for channel.
Top2 (5 bits) = t2
c1 t1 c0 t0
Newtop (10 bits) t8 c5 t7 c4 t6 t5 t4 c3 t3 c2
Put the t-bits next to each other from t8 to t0 and convert it to
decimal ("table index") and the c-bits from c5 bis c0
also but add 1 to get the channel.
Top2 = 11 = binary
01011 (t2 c1 t1 c0 t0)
Newtop = 72 = binary 0001001000 (t8 c5 t7 c4 t6
t5 t4 c3 t3 c2)
Table index = 10001 = 17
Channel = 10011 = 19 + 1 = 20
Step 8 (no difference):
The VCRPLus™ channel has (had) to be mapped to the real channel on the vcr.
With the time
index you get time and duration from the according table.
If (in step 1) you had a 9-digit-number you wrote down the first
digit. Add it to the beginning time and subtract it from the
duration.
Table index = 17 =
"Beginning 9:00 pm, duration 120 minutes"
VCRPlus channel 20 (yields to whatever vcr channel it is mapped)
Day = 8
Minute 3 from step 1 yields "05/08/2001, beginning 9:03
pm, duration 117 minutes"
Encode:
The simplifications I made simplified the reverse of stepe 5 and 2 of decoding really!
It is assumed that
your vcr's date is set to 05/01/2001 to 05/07/2001!
05/08/2001, VCRPlus channel 20,
9:00 pm, duration 120'
1. Convert channel
(subtract 1 from VCRPlus!) and table index to binary.
Channel = 20 - 1 = 19 = 10011
Table index = 17 = 10001
2. Rearrange the
channel and table index bits according to step 7 of decoding to
get Top2 and Newtop and convert it to decimal:
Top2 = 01011 = 11
(t2 c1 t1 c0 t0)
Newtop = 0001001000 = 72 (t8 c5 t7 c4 t6 t5 t4 c3
t3 c2)
3. Compute Bottom
as (Day - 1) * 32 + 1
Day = 8
Bottom = (8 - 1) * 32 + 1 = 225
4. Compute Top
from Newtop:
Subtract the next to last digit from the last digit (modulo 10)
to yield the last digit of the new number,
Subtract from the next to last digit the digit left of it (modulo
10) to yield the next to last digit of the new number etc.
Subtract the last digit of the day from the first digit (modulo
10) for the first digit of the new number.
The two-digit year modulo 16 (plus 1) tells us how often to do
this process.
If Top has fewer digits than Newtop repeat until the number of
digits are equal.
Newtop = 72
Day = 8
Year modulo 16 = 1, thus we do the process twice.
Last digit new number = 2 - 7 = 5
Next to last digit new number = 7 - 8 (day) = 9
New number = 95 (if this is the last
phase this number will be Top otherwise you continue with this
number!)
Last digit new number = 5 - 9 = 6
Next to last digit new number = 9 - 8 (day) = 1
New number = 16 (if this is the last
phase this number will be Top!)
(Top = 16)
5. Up to now the
simplest way to compute and/or understand the still needed Offset
is by computing it the same way as in step 5 of decoding
(There is an easier way to compute but more difficult to explain
and understand if you take the underlined digits of the previous
step and add it (modulo 10) to the Offset you got as described
two lines below!)
Top = 16, Day = 8. Year =
01 (only last two digits!)
Offset = (normal addition of digits of Top) 1 + 6 = 7
Year modulo 16 = 1, thus we do the process twice.
Last digit new number = 1 + 6 + 8 (day)= 5
Next to last digit new number = 1 + 8 (day) = 9
New Number = 95
Offset = 7 + 5 = 12
Last digit new number = 9 + 5 + 8 (day) = 2
Next to last digit new number = 9 + 8 (day) = 7
New Number = 72 ( the Newtop we started with!)
Offset = 12 + 2 = 14
(Offset = 14)
6. From the
formula Top2 = (Rem + Day *
(Month+1) + Offset) modulo 32 from step 6 od decoding we're now
able to compute the last missing number Rem.
Day = 8
Month = 5
Offset = 14
Top2 = 11
11 = (Rem + 8* (5+1) + 14) (modulo 32)
Rem = 11 - (8* (5+1) + 14) = 11 - (48 + 14) = -51 = 13 (because
of modulo 32!)
7. Bottom = Bottom
+ Rem
Code number = (Top * 1000) + Bottom
Rem = 13
Bottom = 225
Top = 16
Bottom = 225 + 13 = 238
Code number = 16000 + 238 = 16238
8. Last step:
"permutate" the code number to yield the VCRPlus number.
To get the 1. digit of the new number subtract the 2. digit of
the code number from the 1. digit of the code number (modulo 10).
For the 2. digit subtract the 3. from the 2. digit (modulo 10)
etc.
Repeat this process two more times.
If the VCRPlus number is shorter than the code number do the
process over. Otherwise FINISHED!
Code number = 16238
1. digit new number = 1 - 6 = 5
2. digit: 6 - 2 = 4
3. digit: 2 - 3 = 9
4. digit: 3 - 8 = 5
5. digit: 8
New number: 54958
5 - 4 = 1
4 - 9 = 5
9 - 5 = 4
5 - 8 = 7
8
New number: 15478
1 - 5 = 6
5 - 4 = 1
4 - 7 = 7
7 - 8 = 9
8
Hence VCRPlus code = 61798
(www.zelczak.com/vcrplus.htm)