[c] Prüfsumme / Checksum

xiconfjs

Grünschnabel
Hi,

ich würde gern eine möglichkeit wissen, eine Prüfsumme ohne will aufwand und Libaries zu erstellen. Sie sollte immer eine feste Größe haben, egal, ob sie von einem oder 5000 Zeichen erstellt wird. Ähnlich md5, sha1 und co. wäre nicht schlecht. Ich hab mir schon überlegt den String, von dem dann die Prüfsumme genommen wird, in gleichgroße Teile z.b. aka 64 Bit zu teilen, und diese dann nach Binär zu formatieren. Dann dann immer 2 64-Bit-Binär-String-Stücke addieren, und diese dann durch 2 Teilen. Dann wieder die entstandenen Teile durch 2 Teilen, und immer weiter, bis eine festgelegte Länge entstanden ist. Fehlende Zeichen werden durch Null ersetzt.

Könnte man das so realisieren oder gäbe es da große Probleme. Und wenn, wie wäre die schnellste und beste Methode.

Alles am besten in ANSI-C :D


mfg -=|XiCoN|[FJS]=-
 
Ich kenn mich jetzt nicht so gut damit aus.. aber am leichtesten ist es sicherlich in einer Code-Suchemaschine (z.B. Google Code-Search) nach einen bereits implimentierten sha-1 Funktion zu Suchen. Da wird es mit Sicherheit welche geben, die das komfortabel als Header + .c anbieten und unter einer frei verwendbaren Lizienz anbieten.
Einen eigenen Algorithmus würde ich nicht verwenden. Hinter den bekannten Hash-Verfahren steckt einiges an mathematischen Wissen. Da kommt ein "auf die schnelle" ausgedachter eingener Algorithmus nicht dran.
 
ich hab mal was probiert :D
Zwar erstmal nur bis 1023 Zeichen, aber 1. reicht das für mich und 2. kann man das leicht erweitern. Ich hätte gern eure Meinung zu der Sicherheit der Hashs und auch z.B. zu dem Sicherheitrisiko "gets()".

Code:
#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;
int main()
{
	int i=0;
	int i2=0;
	int array_size = 1024;
	int teiler=0;
	char buchstaben[1024];
	float zahlen[1024];
	float zs1[512];
	int zs1_counter=0;
	float zs=0;
	int len=0;
	int fehlen=0;
	int hash_len;
	int hash_fehlen;
	teiler=array_size;
	cout << "Bitte den zu hashenden Code eingeben (max " << array_size-1 << " Zeichen):" << endl;
	gets(buchstaben);
	len=strlen(buchstaben);
	if(len>=array_size)
	{
		cout << "Der Code übersteigt die maximale Groeße von " << array_size-1 << " Zeichen " << endl;
		exit;
	}
	for(i=0;i<len;i++)
	{
		zahlen[i]=buchstaben[i]+128;
	}

	fehlen=array_size-len;
	if(fehlen>0)
	{
		for(i=(array_size-1);i>=len;i--)
		{
			zahlen[i]=128;
		}
	}
	for(i=0;i<array_size;i++)
	{
		zs1[zs1_counter]=(zahlen[i]*zahlen[i+1]);
		if(zs1[zs1_counter] >= teiler) zs1[zs1_counter] = zs1[zs1_counter]/teiler;
		zs1_counter++;
		i++;
	}
	array_size=array_size/2;
	while(array_size>1)
	{
		i=0;
		zs1_counter=0;
		for(i=0;i<array_size;i++)
		{
			zs1[zs1_counter]=(zs1[i]*zs1[i+1]);
			if(zs1[zs1_counter] >= teiler) zs1[zs1_counter] = zs1[zs1_counter]/teiler;
			zs1_counter++;
			i++;
		}
		array_size=array_size/2;
	}
	while(zs1[0]<100000)
	{
		zs1[0]=zs1[0]*10;
	}
	char hash[9];
	ltoa (zs1[0], hash, 10);
	hash_len=strlen(hash);
	hash_fehlen=8-hash_len;
	if(hash_fehlen>0)
	{
		for(i=(8-1);i>=hash_len;i--)
		{
			hash[i]='0';
		}
	} 
	hash[8]='\0';

	cout << "------------------------------------" << endl;
	cout << "Ergebnis: " << hash << endl;
	cout << "------------------------------------" << endl;

	
   return 0;
}

Code:
Eingabe: sjkhdfkjsdf896sd8f76s87d6f8s76d9f86s98d7f&(/%/%&(/&(/&(&/&/(%/%
Ausgabe: 70706800

Eingabe: Sjkhdfkjsdf896sd8f76s87d6f8s76d9f86s98d7f&(/%/%&(/&(/&(&/&/(%/%
Ausgabe: 61395600

Eingabe: 76sdf876s8df7658s5g85df76g57sd6f5g76df5
Ausgabe: 14730000

Eingabe: 76sdf876s8df7658s5385df76g57sd6f5g76df5
Ausgabe: 11414100

Eingabe: 1
Ausgabe: 35400000

Eingabe: 2
Ausgabe: 35600000

Eingabe: ~ (1023 mal)
Ausgabe: 68712500
 
Zu gets(): Nimm fgets(variable, AnzahlDerEinzulesenedenZeichen, stdin) um ein Speicher-Überlauf zu vermeiden.

Zum Algorithmus: Ist dir Dir aufgefallen, dass deine letzten beiden Zifferen immer 00 sind? Das sind nur 1.000.000 verschiedene Hashwerte. Für ein Passwort ist das auf jeden Fall unzureichend, für eine Prüfsumme musst du selbst entscheiden, ob dir das genügt. Ein vorgefertigter Algorithmus würde dir um den Faktor 10e40 und mehr Kombinationen geben. Und du müsstest dir keine Gedanken über Kollisionen machen...
 
1. danke für den Tipp mit gets
2. Das mit den beiden 00 ist mir nicht nur aufgefallen, das ist absicht ;) Da ich 8 Stellige Zahlen brauchen :D
3. Für mich reicht es...im Endeffekt entscheidet dieser Hash bloß, ob sich die Hardware von 2 Rechnern unterscheidet. Und da hab ich so viel schon probiert, und das klappt wunderbar...in dieser Hinsicht bin ich ein bissel stolz auf mich :D

Und falls es diese Art der Hasherstellung noch nicht gibt, dann taufe ich ihn hiermit zu:
XLSH1 --> XiconLowSecureHash1 :D
 
Und falls es diese Art der Hasherstellung noch nicht gibt, dann taufe ich ihn hiermit zu:
XLSH1 --> XiconLowSecureHash1 :D

Der Code mag ja vieles sein, aber von einer Hashfunktion ist das ebensoweit entfernt wie ein Toaster von einem Taschenrechner. Und was soll das ganze mit Security zu tuen haben?

Als Beispiel: Die folgenden fünf Sätze ergeben genau den gleichen Hashwert bei Deiner Funktion:

"Peter hat heute keine Zeit"
"hat Peter Zeit heute keine"
"keine Zeit hat Peter heute"
"heute hat keine Zeit Peter"
"he Pate keine Zitter huete"

Oder anderes ausgedrückt, Du kannst die Zeichen innerhalb eines Strings beliebig mischen, solange die Anzahl der einzelnen Zeichen gleich bleibt, ändert sich auch dein "Hashwert" nicht. Damit dürfte deine Hashfunktion eine Kollisionsquote von gut 90% erreichen...
 
Für C++ - Code aber leider sehr unzureichend abstrahiert, gekapselt und kommentiert und daher nicht empfehlenswert als Opensource-Code.

[edit]Tolle Anmerkung jsendrow!![/edit]
 
Zuletzt bearbeitet:
Der Code mag ja vieles sein, aber von einer Hashfunktion ist das ebensoweit entfernt wie ein Toaster von einem Taschenrechner.
Naja, musst ja nicht gleich bösartig werden...ich habe nicht gesagt, dass diese Art der Hasherstellung anderen bekannteren das Wasser reichen kann, doch im Grundprinzip ist es eine.
Und was soll das ganze mit Security zu tuen haben?
Naja, man kann einfach so, ohne den Quellcode zu kennen, wenn überhaupt, aus dem Hash nicht den eingebenen Text zurückrechnen...was ja ein Aspekt von sicherheit wäre...und außerdem war dieser Name auch nur scherzhaft gemeint, wie man vielleicht aus dem Kontext erkennen kann.
Oder anderes ausgedrückt, Du kannst die Zeichen innerhalb eines Strings beliebig mischen, solange die Anzahl der einzelnen Zeichen gleich bleibt, ändert sich auch dein "Hashwert" nicht. Damit dürfte deine Hashfunktion eine Kollisionsquote von gut 90% erreichen...
Würde sie, wenn die Eingaben vom User variabel wären, was sie aber nicht sind...daher meine ich ja auch, dass es für meinen Zweck reicht.

Aber trotzdem danke für deine ausführliche Analyse meines Programms. Da ich sonst halt nicht wirklich viel mit C/C++ mache, finde ich, dass ich mich einigermaßen wacker geschlagen habe...

Aber ich verstehe das nicht, warum Leute wie z.b. GeHo es schaffen, normal auf Fragen zu antworten und ihre Kommentare zu etwas zu schreiben, und dann wieder andere Leute meinen, immer den dicken raushängen lassen zu müssen...mhhh...

naja jedenfalls einen schönen Tag noch.


P.S.: Weitere Kommentare auf meinen Text sind möglich, aber nicht notwendig.
 
Zurück