Skip to content

Latest commit

 

History

History
167 lines (126 loc) · 4.96 KB

README.md

File metadata and controls

167 lines (126 loc) · 4.96 KB

Einfache URN (Uniform Resource Name) Prüfziffern-Berechnung für den Namensraum nbn / Überprüfung in PHP und Javascript

USN-Servevice der DNB: https://www.dnb.de/DE/Professionell/Services/URN-Service/urn-service_node.html

In PHP kann man die URN-Prüfsumme mit einer Zeile PHP-Code berechnen - ok, es ist eine lange Zeile :-)

# Test-set
$test_org="urn:nbn:de:0183-mbi0003721";
$test_urn=substr($test_org,0,-1);

# Here: One line of code for calculation...
for($code="3947450102030405060708094117############1814191516212223242542262713282931123233113435363738########43", $i=$sum=0, $pos=1; $i<strlen($test_urn); $i++, $sum += ($v1==0)?$v2*$pos++:$pos++*$v1+$v2*$pos++, $purn=$sum/$v2 % 10) list($v1,$v2)=array(substr($code,(ord(strtoupper(substr($test_urn,$i,1)))-45)*2,1),substr($code,(ord(strtoupper(substr($test_urn,$i,1)))-45)*2+1,1));

# Output / Check
printf("%s %s => %s (%s)\n", $test_urn,$purn,$test_urn.$purn,$test_urn.$purn==$test_org?"OK":"Error");

Or Javascript:

function calc_urn_checksum(test_urn)
{
        //var test_urn='urn:nbn:de:hbz:79pbc-201405121';
        var code='3947450102030405060708094117############1814191516212223242542262713282931123233113435363738########43';
        for(var i=0,sum=0,gewichtung=1; i<test_urn.length;i++){
                var x=test_urn.toUpperCase().charCodeAt(i)-45;
                var v1= code.substr(x*2,1);
                var v2= code.substr(x*2+1,1);
                sum += (v1==0)?v2*(gewichtung++):v1*(gewichtung++)+v2*(gewichtung++);
        }
        return Math.floor(sum/v2) % 10;
}

Oder bash:

get_checkcipher() {

    weight=1
    sum=0

    get_charcode() {
      LC_CTYPE=C printf '%d' "'$1"
    }

    urnncs=$(printf '%s\n' ${1} | awk '{ print toupper($0) }')

    code="3947450102030405060708094117############1814191516212223242542262713282931123233113435363738########43"

    for (( i=0; i<${#urnncs}; i++ )); do
      
      codeposi=$(($(get_charcode ${urnncs:$i:1})-45))
      
      sum1=${code:$(($codeposi*2)):1}
      sum2=${code:$(($codeposi*2+1)):1}

      if [ $sum1 -eq 0 ]
      then
        sum=$(($sum+$sum2*$weight))
        weight=$(($weight+1))
      else
        sum=$(($sum+$sum1*$weight))
        weight=$(($weight+1))
        sum=$(($sum+$sum2*$weight))
        weight=$(($weight+1))
      fi
    
    done

    float=$(awk -v a="$sum" -v b="$sum2" 'BEGIN {print a / b }')
    
    echo $((${float%%.*} % 10))
}

Der Algorithmus zur Bildung der NBN-Prüfziffer im Rahmen des Projektes CARMEN-AP4 „Persistent Identifier and Metadata Management in Science“ stammt von 2001. Inzwischen sind Prüfziffern nicht mehr notwendig.

Das Verfahren ist hier sehr gut beschrieben: http://www.pruefziffernberechnung.de/U/URN.shtml:



Umsetzungstabelle Buchstaben und Zahlen nach Zahlen (festgelegt)

0 -> 1
1 -> 2
2 -> 3
3 -> 4
4 -> 5
5 -> 6
6 -> 7
7 -> 8
8 -> 9
9 -> 4,1
	
A -> 1,8
B -> 1,4
C -> 1,9
D -> 1,5
E -> 1,6
F -> 2,1
G -> 2,2
H -> 2,3
I -> 2,4
J -> 2,5
	
K -> 4,2
L -> 2,6
M -> 2,7
N -> 1,3
O -> 2,8
P -> 2,9
Q -> 3,1
R -> 1,2
S -> 3,2
T -> 3,3
	
U -> 1,1
V -> 3,4
W -> 3,5
X -> 3,6
Y -> 3,7
Z -> 3,8
- -> 3,9
: -> 1,7

_ -> 4,3 (neu: BSZ)
/ -> 4,5 (neu: Projekt STD)
. -> 4,7 (neu: Projekt STD)
+ -> 4,9 (neu: Projekt STD)


Nach der Zeichensubstitution kann die Prüfziffer errechnet werden.

    Alle Ziffern werden von links nach rechts, beginnend mit der ersten Ziffer, mit ihrer Position in der Ziffernfolge gewichtet.
    Die Produkte werden summiert.
    Die Produktsumme wird durch die letzte Stelle des URN dividiert.
    Die Einerstelle des Quotienten ist die Prüfziffer.

Der Algorithmus von mir setzt auf die ASCII-Reihenfolge und somit auf eine Verweis-auf-Verweis Auflösung:


ASCII Zeichen : -  .  /  0  1  2  3  4  5  6  7  8  9  : [ Toter Bereich ]  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z              _
ASCII Wert Dez:45 46 47 48 49 50 51 52 53 54 55 56 57 58                   65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90             95
URN Value     :39 47 45 01 02 03 04 05 06 07 08 09 41 17 ## ## ## ## ## ## 18 14 19 15 16 21 22 23 24 25 42 26 27 13 28 29 31 12 32 33 11 34 35 36 37 38 ## ## ## ## 43
Array Pos     : 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50  (Char-Wert - 45)
	
Beispiel: urn:nbn:de:0183-mbi0003721 - hierbei ist die Prüfziffer 1
        
U -> 1,1 ->> 1 *  1 =  1 (Der 2. Multiplikator ist die Gewichtung, die hochgezählt wird)
             1 *  2 =  2
R -> 1,2 ->> 1 *  3 =  3
             2 *  4 =  8
N -> 1,3 ->> 1 *  5 =  5
             3 *  6 = 18	
[...]
2 ->   3 --> 3 * 29 = 87
                   ------
                    2855

		Zum Ende die Summe durch 3 teilen (letzte Wert) und hiervon die Einerstelle verwenden. 	
		
		2855 / 3 = 951.6 --> (951.6 mod 10) = 1