292 lines
5.5 KiB
Plaintext
292 lines
5.5 KiB
Plaintext
! CRC-12 Pruefsummenberechnung
|
|
!
|
|
! Verwendetes Generatorpolynom: G(x)=x^12+x^11+x^3+x^2+x+1 (== 1100000001111)
|
|
|
|
let
|
|
! Diverse Register
|
|
var r24 : array 24 of Integer; ! 3 zu checkende bytes
|
|
var r36 : array 36 of Integer; ! r24 mit angehaengten Nullen
|
|
var r13 : array 13 of Integer; ! Generatorpolynom
|
|
var rcs : array 13 of Integer; ! Gesamtchecksumme
|
|
|
|
! Generator in Bitschreibweise und als Integersumme
|
|
const G ~ [1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1];
|
|
var g : Integer;
|
|
|
|
! Potenzen schlagen wir nach
|
|
const pot8 ~ [128, 64, 32, 16, 8, 4, 2, 1];
|
|
const pot13 ~ [4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1];
|
|
|
|
! Drei einzulesende Bytes -> r24
|
|
var chr1 : Char;
|
|
var chr2 : Char;
|
|
var chr3 : Char;
|
|
|
|
! Triangle ist gut im "hinter der Datei lesen", also doch selber machen
|
|
var readbehindeof : Boolean;
|
|
|
|
! "counter" zaehlt die 1024-Byte-Blocks in "blocks"
|
|
var counter : Integer;
|
|
var blocks : Integer;
|
|
|
|
! "i" wie Integer-Hilfsvariable
|
|
var i : Integer;
|
|
|
|
! Gesamtchecksumme als Int
|
|
var checksum : Integer;
|
|
|
|
! Debug
|
|
proc showr13() ~
|
|
begin
|
|
i := 0;
|
|
while (i<13) do
|
|
begin
|
|
putint(r13[i]);
|
|
i := i+1;
|
|
end;
|
|
puteol();
|
|
end;
|
|
|
|
! Debug
|
|
proc showr24() ~
|
|
begin
|
|
i := 0;
|
|
while (i<24) do
|
|
begin
|
|
putint(r24[i]);
|
|
i := i+1;
|
|
end;
|
|
puteol();
|
|
end;
|
|
|
|
! Debug
|
|
proc showr36() ~
|
|
begin
|
|
i := 0;
|
|
while (i<36) do
|
|
begin
|
|
putint(r36[i]);
|
|
i := i+1;
|
|
end;
|
|
puteol();
|
|
end;
|
|
|
|
|
|
! XOR zweier Bits
|
|
func xor(val1: Integer, val2: Integer) : Integer ~
|
|
if (val1 \= val2) then
|
|
1
|
|
else
|
|
0
|
|
;
|
|
|
|
! CRC-12 auf 3 Bytes berechnen
|
|
proc crc() ~
|
|
let
|
|
var i : Integer;
|
|
var j : Integer;
|
|
var k : Integer
|
|
in
|
|
begin
|
|
! r36 von links auffüllen, Rest nullen
|
|
i := 0;
|
|
while (i < 24) do
|
|
begin
|
|
r36[i] := r24[i];
|
|
i := i + 1;
|
|
end;
|
|
while (i < 36) do
|
|
begin
|
|
r36[i] := 0;
|
|
i := i + 1;
|
|
end;
|
|
|
|
! Division Modulo 2 (eigentlich XOR)
|
|
j := 0;
|
|
while (j < 22) do
|
|
begin
|
|
i := 0;
|
|
k := 0;
|
|
while (i < 13) do
|
|
begin
|
|
k := r36[i+j] * pot13[i] + k;
|
|
i := i + 1;
|
|
end;
|
|
|
|
if (k >= g) then
|
|
begin
|
|
i := 0;
|
|
while (i < 13) do
|
|
begin
|
|
r36[i+j] := xor(r36[i+j], r13[i]);
|
|
i := i + 1;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
i := 0;
|
|
while (i < 13) do
|
|
begin
|
|
r36[i+j] := xor(r36[i+j], 0); ! sprich: einfach weitergehen und nix machen
|
|
i := i + 1;
|
|
end;
|
|
end;
|
|
j := j + 1;
|
|
end;
|
|
|
|
! Leider noch unbefriedigend...
|
|
! Gesamtchecksumme erreicht schnell 2^12-1,
|
|
! evtl. faellt mir noch was besseres ein
|
|
! (Triangle gibt bei Zahlen > maxint einfach 0 aus, hmmm....)
|
|
i := 0;
|
|
while (i < 13) do
|
|
begin
|
|
! r13[i] := r36[i+24];
|
|
rcs[i] := xor(r13[i], rcs[i]);
|
|
i := i + 1;
|
|
end;
|
|
end;
|
|
|
|
! Lese Wert nach r24, wobei place=1=linkesByte=MSB, place=2=mittleresByte, und place=3=rechtesByte=LSB
|
|
proc load(place: Integer, val: Integer) ~
|
|
let
|
|
var i : Integer;
|
|
var j : Integer;
|
|
var v : Integer;
|
|
|
|
! Ist Bit mit Wertigkeit div gesetzt?
|
|
func bitset(val: Integer, div: Integer) : Integer ~
|
|
if (div = 0) then
|
|
0
|
|
else
|
|
if ((val / div) > 0) then
|
|
1
|
|
else
|
|
0
|
|
in
|
|
begin
|
|
v := val;
|
|
i := (place-1)*8;
|
|
j := 0;
|
|
|
|
! ganzes Byte in r24 einsetzen
|
|
while (j < 8) do
|
|
begin
|
|
r24[i] := bitset(v, pot8[j]);
|
|
if (r24[i] = 1) then
|
|
v := v - pot8[j]
|
|
else
|
|
;
|
|
i := i + 1;
|
|
j := j + 1;
|
|
end;
|
|
end;
|
|
|
|
! 24 bits einlesen, falls möglich
|
|
proc readin() ~
|
|
let
|
|
var n1 : Integer;
|
|
var n2 : Integer;
|
|
var n3 : Integer;
|
|
var i : Integer;
|
|
var testeof : Boolean
|
|
in
|
|
begin
|
|
counter := 0;
|
|
blocks := 1;
|
|
readbehindeof := false;
|
|
|
|
eof(var testeof);
|
|
while \testeof do
|
|
begin
|
|
chr1 := ' ';
|
|
chr2 := ' ';
|
|
chr3 := ' ';
|
|
get(var chr1);
|
|
get(var chr2);
|
|
get(var chr3);
|
|
n1 := ord(chr1);
|
|
n2 := ord(chr2);
|
|
n3 := ord(chr3);
|
|
! Falls wir ueber das Dateiende hinausgelesen haben,
|
|
! dann von hinten den "Muell" wegmachen und fuer uns
|
|
! in "readbehindoef" klarstellen, dass wir definitiv
|
|
! fertig sind
|
|
if (n3 < 0) then
|
|
begin
|
|
counter := counter-1;
|
|
n3 := 0;
|
|
if (n2 < 0) then
|
|
begin
|
|
counter := counter-1;
|
|
n2 := 0;
|
|
if (n1 < 0) then
|
|
begin
|
|
readbehindeof := true;
|
|
counter := counter-1;
|
|
n1 := 0;
|
|
end
|
|
else
|
|
;
|
|
end
|
|
else
|
|
;
|
|
end
|
|
else
|
|
;
|
|
! nun die Bytes ins Register r24 schieben und die CRC darueber berechnen
|
|
if (\ readbehindeof) then
|
|
begin
|
|
load(1, n1);
|
|
load(2, n2);
|
|
load(3, n3);
|
|
crc();
|
|
end
|
|
else
|
|
;
|
|
! und als Bonus die Anzahl der 1k-Bloecke bestimmen
|
|
counter := counter+3;
|
|
if (counter >= 1024) then
|
|
begin
|
|
counter := 0;
|
|
blocks := blocks + 1;
|
|
end
|
|
else
|
|
;
|
|
|
|
eof(var testeof);
|
|
end;
|
|
end
|
|
|
|
in
|
|
begin
|
|
! Initalisierungen, Generatorpolynom -> r13 und als Integer
|
|
i := 0;
|
|
g := 0;
|
|
checksum := 0;
|
|
while (i < 13) do
|
|
begin
|
|
rcs[i] := 1;
|
|
r13[i] := G[i];
|
|
g := (r13[i] * pot13[i]) + g;
|
|
i := i + 1;
|
|
end;
|
|
|
|
! von STDIN lesen und CRC-12 berechnen
|
|
readin();
|
|
|
|
! Checksumme aus der Bitschreibweise errechnen
|
|
i := 0;
|
|
while (i < 12) do
|
|
begin
|
|
checksum := rcs[i+1] * pot13[i+1] + checksum;
|
|
i := i + 1;
|
|
end;
|
|
|
|
! Checksumme und Blocks ausgeben
|
|
putint(checksum);
|
|
put(' ');
|
|
putint(blocks);
|
|
puteol();
|
|
end;
|