ISO IEC_7064 - homebeaver/ungueltig GitHub Wiki
ISO/IEC 7064 Normierung
Der Text der ISO/IEC 7064 Normung ist kostenpfichtig (1983 7/13 + 2003 5/13). Beschreibung aus Wikipedia : in der Norm werden fünf reine Systeme (pure) mit einen Divisor und drei hybride Systeme formal beschrieben.
image/ISO-IEC-7064-2003_11.PNG
Eine Implementierung gibt es hier.
Pure Systems
- MOD 11-2 und MOD 97-10 für numerische Zeichenketten
- MOD 661-26 für alphabetische Zeichenketten
- MOD 37-2 und MOD 1271-36 für alphanumerische Zeichenketten
Benennung: die erste Zahl hinter “MOD” in der (modulus $${M}$$) Teilungsrest/Divisor, die zweite ist die Basiszahl ($${r}$$ radix).
Es wird unterstellt, dass das Prüfzeichen $${ a_1 }$$ das rechte Zeichen einer Zeichenkette ist. Eine Zeichenkette $${ a_n , \dots , a_1 }$$ ist gültig, wenn
$${ \sum_{i=1}^n a_i \cdot r^{i-1} \space \equiv 1 \space {mod} \space M }$$
Prüfzeichen berechnen
Zwei Berechnungsmethoden für das Prüfzeichen werden vorgestellt
- Pure system recursive method
- Pure system polynomial method
- Für MOD 97-10 wir außerdem ein vereinfachtes Verfahren vorgestellt.
recursive method
Eine iterative Implementierung kann in Wikipedia nachgeschlagen werden. Oder hier.
polynomial method
$${ \sum_{i=1}^n a_i \cdot w_i \space \equiv 1 \space {mod} \space M }$$
The polynomial method for the pure systems is computed by multiplying the value for each character in the string by $${ r^{i-1} }$$ or by $${ r^{i-1} \left( \space Mod \space M \space \right) }$$, which is denoted by the weight $${ w_i }$$.
Multiply the character values by their weights, and then add the products. Strings including the check character are valid if the sum of these products is congruent to 1 (mod M).
Weights
Precalculated weights are defined for the first fifteen positions. The series can be extended indefinitely, but do not use java Math.pow
for calculation of high power results, f.i. $${ 10^{23} }$$.
Math.pow(getRadix(), n) % getModulus(); // do not use for high pow results!
// calculate instead:
long p = getRadix(); // r^1
for (int i = 1; i < n; i++) {
p = p * getRadix();
if (p > Integer.MAX_VALUE) {
p = p % getModulus();
}
}
p = p % getModulus(); // the weight
Hybrid Systems
Hybride Systeme haben zwei Divisoren, die in der Bezeichnung des Verfahrens stehen. In der Norm werden sie $${ M+1 }$$ und $${ M }$$ genannt. $${ M }$$ entspricht der Anzahl der Zeichen, aus denen das Prüfzeichen bestehen kann.
Daher die Benennungen:
- MOD 11,10 für numerische Zeichenketten
- MOD 27,26 für alphabetische Zeichenketten
- MOD 37,36 für alphanumerische Zeichenketten
Berechnungsmethode
Es gibt nur eine Berechnungsmethode, die rekursiv definiert ist.
With the index $${ j = 1 \dots n }$$ where n is the number of Characters in the string including the Check Character and defining $${ P_j = M }$$ for $${ j = 1 }$$, calculate
$${ S_j = P_j \mid _ \left( M+1 \right) + a_ \left( n-j+1 \right) }$$
$${ P_{j + 1} = S_j \parallel _M \times 2 }$$
where
- $${ \parallel _M }$$ is the integer remainder after dividing by $${ M }$$; if this ist zero then the value $${ M }$$ shall bei substituted;
- $${ \mid _ \left( M+1 \right) }$$ is the remainder after dividing by $${ M+1 }$$; the reminder is never zero after this Operation;
- $${ a_ \left( n-j+1 \right) }$$ is the character value.
For checking purposes the string ist taken as correct if $${ S_n \equiv 1 \space ( {mod} \space M ) }$$. When generating a check character, $${ a_1 }$$ ist chosen so that $${ P_n + a_1 \equiv 1 \space ( {mod} \space M ) }$$
// iterativ in Java:
int product = getOtherModulus(); // M : 10, 26 oder 36
int sum = 0;
for (int i = 0; i < code.length(); i++) {
sum = toInt(code.charAt(i)) + product;
sum = sum % getOtherModulus();
product = 2 * (sum == 0 ? getOtherModulus() : sum) % getModulus();
}
int pz = getModulus() - product;
return pz == getOtherModulus() ? 0 : pz;
Führende Nullen in Zeichenketten und Zero Check
Aus führende Nullen resultieren verschiedene Prüfzeichen. Beispiel MOD 11,10:
- Die Prüfziffer für "1" ist
9
, - aber die Prüfziffer für "00000001" ist
1
.
Das gilt auch für Zero Zeichenketten:
- Die Prüfziffer für "0" ist
2
, - die Prüfziffer für "00" ist
4
, - die Prüfziffer für "000" ist
8
, - die Prüfziffer für "0000" ist
5
und - die Prüfziffer für leeren String "" ist
1
.
Die Prüfziffer für Zero Zeichenkette ist gleich $${ 2^{Anzahl Nullen} \left( \space Mod \space 11 \space \right)}$$.