# Prüfziffer



## Destiny1985 (3. Feb 2005)

Gibt es Methoden mit denen ich die Prüfziffer einer beliebig langen Zahl berechnen kann ? Würde mir sehr helfen


----------



## mic_checker (3. Feb 2005)

Kommt drauf an was für Prüfziffern? Glaube kaum das du z.B. MessageDigests verwenden willst (außer du hast ne kryptographische Anwendung). 

btw. wofür neuer thread? das hätte doch auch im alten geklärt werden können.


----------



## Destiny1985 (3. Feb 2005)

ja, aber so ist der thread-name auf das thema bezogen, der andere geht ja darum wie ich was als .txt speichere....das mit der püfziffer ist kotzig schwer... :<


----------



## mic_checker (3. Feb 2005)

jetzt weiss ich immer noch nicht ob du die prüfziffer nach nem best. verfahren generieren willst oder nicht....welche anforderungen werden an die prüfziffer gestellt?


----------



## Destiny1985 (3. Feb 2005)

also...das prog soll wie folgt werden:

man kann erst auswählen ob man eine oder mehrere zahlen eingeben will...also einzelzahl oder von - bis...

die zahl die man eingeben kann soll 2 stellig - 13 stellig sein. Das verfahren zur Berechnung der prüfziffer ist das geläufige, wie es zb bei EAN-Nummern genutzt wird.

man nimmt die letzte ziffer (einer) * 3, die nächste (zehner) * 1, die nächste (hunderter) wieder * 3 und so weiter....diese werte addiert man dann ( man bekommt zb 84 raus ) . die prüfziffer ist die differenz zum nächsten vollen zehner...in diesem fall wäre es die 6 !

mfg


----------



## mic_checker (3. Feb 2005)

aber damit hast du dir wohl die lösung des probs fast schon selber gegeben.

Du hast die Zahl und du kennst das Verfahren. Wodran liegt es denn jetzt? Poste doch mal deinen Ansatz und wir sehen was (vielleicht) falsch ist.


----------



## Destiny1985 (3. Feb 2005)

Ich kapier nicht wie ich es kompakt mache, das der checkt wie lang die Zahl ist und entsprechend die Berechnung der prüfziffer durchführt...muss ja auch erst die zahl in ihre Ziffern splitten und so...kapier das nicht....Meinen Ansatz hab ich gerade komplett gelöscht weil er so beschissen war...


----------



## mic_checker (3. Feb 2005)

So z.B.


```
int num = .... //die zahl deren prüfziffer du berechnen willst
int laenge = String.valueOf(num).length();
```

Müsste gehen, sicher nicht das effizienteste, aber sollte halt klappen.

Mit dem Rest kommst du klar?


----------



## Destiny1985 (3. Feb 2005)

Komm damit schon nicht klar ich elender n00b 

Was hat das mit dem


```
int laenge = String.valueOf(num).length();
```
auf sich ?


----------



## mic_checker (3. Feb 2005)

Aus der API:



> *static String 	valueOf(int i)*
> Returns the string representation of the int argument.



Du machst daraus nen String, berechnest seine Länge und weisst diese Länge der Variablen zu.

Der Rest is auch nicht so schwer, der Modulo Operator kann hilfreich sein sag ich nur.

Bei Problemen halt posten.


----------



## Destiny1985 (3. Feb 2005)

mic_checker hat gesagt.:
			
		

> ... der Modulo Operator kann hilfreich sein sag ich nur....



achsooo...der...uiui ich mach es glaub ich lieber übel kompliziert...dann kapier ich es zumindest... oO


----------



## mic_checker (3. Feb 2005)

wieso?

sagen wir du hast die zahl 12345.

Für die Prüfziffer musst du immer die letzte Ziffer kennen:


```
int num = 12345;

int zahl = num % 10; //in zahl steht jetzt 5
```

Nun musst du das ganze nur noch in eine schleife packen und num entsprechend anpassen (sonst kriegst du jedes mal 5 als letzte ziffer - bezogen auf dieses beispiel). ich sag dafür nur : / 

btw. Modulo ist doch ein schöner Operator, ich weiss gar net wat so viele gegen den haben


----------



## Destiny1985 (3. Feb 2005)

ach sag doch das % modulo heisst...weiss ich das denn ^^

das mit der aufsplittung ist kein prob, das hab ich auch schon fertig...aber ich find den ganzen quellcode "hässlich"...naja ich mach da heute nichts mehr, setz mich morgen wieder dran und poste dann hier auch mal meinen code den ich dann habe...so long..schönen feierabend *gg*

mfg


----------



## mic_checker (4. Feb 2005)

Hab hier mal meine Lösung, ka ob es funzt , ist nur schnell hingeschmiert :


```
public class Pruefziffer
{
	public static void main(String[] args)
	{
//Prüfziffer von num berechnen - ändern wenn gewollt
		int num = 12,cur = 0,sum = 0,zahl = 3;
		int laenge = String.valueOf(num).length();
				
		while(laenge-- > 0)
		{
			cur = num % 10;
			num /= 10;
			sum += cur * zahl;	
			zahl = zahl == 3 ? 1 : 3;		
		}			
		
		if(sum % 10 == 0)
			System.out.println("Prüfziffer = 0");
		else
			System.out.println("Prüfziffer = "+(10 - (sum % 10)));
	}
}
```


----------



## Destiny1985 (7. Feb 2005)

mic bekomm ich auch eine erklärug dazu ^^ will keine fertige lösung sondern es verstehen...

mfg


----------



## Destiny1985 (7. Feb 2005)

So, hab den Programmcode mal ausprobiert, funktionieren tut er, nur ist er inhaltlich falsch, d.h. er berechnet die Prüfziffer nicht richtig...hier nochmal wie das ganze funktioniert:

1. Man hat eine beliebig lange Zahl (max 13 Stellen)

2. Man beginnt von hinten (also von der letzten Ziffer an), die einzelnen Ziffern abwechselnd mit 3 und 1 zu multiplizieren und rechnet die Ergebnisse zusammen.

(Beispiel: Zahl 20315 -> 5*3 + 1*1 + 3*3 + 0*1 + 2*3 = 31)

3. Man subtrahiert das Ergebnis (31) vom nächsten vollen Zehner (in diesem Fall dann die 40), das Ergebnis ist die Prüfziffer der Zahl (40 - 31 = 9 = Prüfziffer)


----------



## Destiny1985 (7. Feb 2005)

Ich korrigiere mich, der Algorythmus ist doch richtig und funktioniert korrekt...ja ist halt Rosenmontag *suff*...

[edit] ABER: Ausführliches testen hat gezeigt das der Algorythmus nur bis 12-stellige Zahlen richtig rechnet...er müsste aber 13-stellige auch können ( -> EAN-Nummer)

Was muss ich dazu ändern ?

mfg [/edit]


----------



## Illuvatar (7. Feb 2005)

Hm probiers mal mit long statt int kann sein dass es daran liegt.


----------



## mic_checker (7. Feb 2005)

Hab deswegen keine Erklärung dabei gepackt weil du ja geschrieben hast du hättest ne Lösung. Aber hier ist ne kurze Erklärung 


```
public class Pruefziffer
{
   public static void main(String[] args)
   {
//Prüfziffer von num berechnen - ändern wenn gewollt
      int num = 12,cur = 0,sum = 0,zahl = 3;
      int laenge = String.valueOf(num).length();
```

Du schaust welche Länge der String hat, der die Zahl repräsentiert, so dass du die "Länge" der Zahl herausfinden kannst.


```
while(laenge-- > 0)
      {
         cur = num % 10;
         num /= 10;
         sum += cur * zahl;   
         zahl = zahl == 3 ? 1 : 3;      
      }
```

Hier findet die Berechnung der Prüfziffer statt.


```
cur=num%10;
```

Liefert als Ergebnis jeweils die "Einer", also die letzte Ziffer der Zahl.


```
num /= 10;
//gleichbedeutend zu num = num / 10;
```

Nun muss die Zahl noch angepasst werden, so dass beim nächsten Durchlauf die neue letzte Ziffer geliefert wird, nicht die alte.


```
sum += cur * zahl;
//sum = sum + (cur * zahl)
```
Zur bisherigen Summe wird die aktuell letzte Ziffer multipliziert mit der jeweiligen Zahl (1 oder 3) hinzuaddiert.


```
zahl = zahl == 3 ? 1 : 3
/* oder:
if(zahl == 3)
zahl = 1;
else
zahl = 3
*/
```

Anfangs die letzte Ziffer wird mit 3 multipliziert,danach ändert sich jeweils die Zahl auf 1, auf 3 etc. Durch diese Abfrage wird sichergestellt , dass tatsächlich mit der richtigen Ziffer multipliziert wird.


```
if(sum % 10 == 0)
         System.out.println("Prüfziffer = 0");
      else
         System.out.println("Prüfziffer = "+(10 - (sum % 10)));
   }
}
```


```
sum % 10
```

Liefert als Ergebnis den Abstand zum nächst größeren Zehner, falls die Modulo Operation 0 liefert so ist die Summe bereits ein Zehner und die Prüfziffer somit 0.

Hmm....müsste mal schauen wodran es liegt das er nur 12-stellige macht...


----------



## Destiny1985 (7. Feb 2005)

Illuvatar hat gesagt.:
			
		

> Hm probiers mal mit long statt int kann sein dass es daran liegt.



Das habe ich schon geändert ... hat auch nicht geholfen :<


----------



## mic_checker (7. Feb 2005)

int hat nen Wertebereich von -2147483648 bis 2147483647. Könnte also tatsächlich sein das es daran liegt.

edit:
hab dein letztes post gerade erst gesehen.....hmm..


----------



## mic_checker (7. Feb 2005)

Notfalls kannst du das ganze ja auch mit String machen, hab bisher nämlich keine Erfahrungen mit BigInteger etc. gemacht.


----------



## Destiny1985 (7. Feb 2005)

lol ok mein fehler...hatte eine variable vergessen auf long umzustellen...jetzt gehts  

*haken mach*


----------



## mic_checker (7. Feb 2005)

arg, hab mich schon gefragt warum du nicht mit long-Wertebereich hinkommst 

Trotzdem hier die Lösung mit Strings


```
public class Pruefziffer {
	public static void main(String[] args) {
		String num = "31313131313131";
		int laenge = num.length(),cur,sum = 0,zahl = 3;
		int ende = laenge-1;
		char ch;
		
		while (laenge-- > 0) {	
			/* Speichere das letzte Zeichen des Strings in ch */	
			ch = num.charAt(ende--);
			
			/* 
			* ch ist char, deshalb müssen wir '0' subtrahieren um den tatsächlichen Zahlenwert zu 
			* erhalten. Danach multiplizieren wir diese Zahl mit 3 oder 1.
			*/
			sum += (ch - '0') * zahl;
			zahl = zahl == 3 ? 1 : 3;		
		}			
		
		if(sum % 10 == 0)
			System.out.println("Prüfziffer = 0");
		else
			System.out.println("Prüfziffer = "+(10 - (sum % 10)));
	}
}
```

Müsste eigentlich auch klappen. Btw. die Überprüfung ob in dem String nur Zahlen drin vorkommen hab ich mir erspart, dann berechnest du halt die Prüfziffer von nem Wort im Fall der Fälle


----------



## Destiny1985 (7. Feb 2005)

Mir ist gerade ein neues Prob aufgetaucht. Will das Porgramm so erweitern das man einen Zahlenbetreich angibt und er für alle zahlen die Prüfziffer ausgibt. Das programm läuft, die erste Prüfziffer stimmt, aber ab der 2. wird es immer falsch....hier der relevante Code

```
public static void Berechnung(long startZahl, long endZahl)
  {
    int zaehler = (int)(endZahl - startZahl);
    long zahl = startZahl;
  
    while ( zaehler != 0 )
    {
      long cur = 0,sum = 0,var = 3;
      long laenge = String.valueOf(zahl).length();

      while(laenge-- > 0)
      {
        cur = zahl % 10;
        zahl /= 10;
        sum += cur * var;
        var = var == 3 ? 1 : 3;
      }

      if(sum % 10 == 0)
        System.out.println("\nDie Pruefziffer ist 0");
      else
        System.out.println("\nDie Pruefziffer ist " + (10 - (sum % 10)));
      
      zaehler = zaehler - 1;
      zahl = zahl + 1;
    }
  }
```

Woran liegts ?

mfg


----------



## Destiny1985 (7. Feb 2005)

achja, eine Anmerkung...ab der 2. immer falsch heisst, das wenn ich zb zahlenbereich von 210 bis 220 habe er mir dann ausgibt

```
Die Prüfziffer ist 3
Die Prüfziffer ist 7
Die Prüfziffer ist 7
Die Prüfziffer ist 7
Die Prüfziffer ist 7
Die Prüfziffer ist 7
Die Prüfziffer ist 7
Die Prüfziffer ist 7
Die Prüfziffer ist 7
Die Prüfziffer ist 7
```

...und komischerweise ist der 2. IMMER 7...egal welchen zahlenbereich ich habe...


----------



## mic_checker (7. Feb 2005)

```
zahl = zahl + 1;
```

Nachdem die while Schleife abgearbeitet wurde ist zahl immer 0, nun inkrementierst du zahl, so dass zahl 1 ist.

Ich denke du willst aber das:


```
zahl = ++startZahl;
```


----------



## Destiny1985 (7. Feb 2005)

aja ^^ ist was dran  ok muss jetzt nur mal nachrechnen ob die ergebnisse, die er jetzt spruckt, richtig sind...

thx schonmal


----------

