Lineares Schieberegister
lima-city → Forum → Programmiersprachen → C/C++ und D
assembler
bit
buffer
byte
code
container
dank
eins
frage
linear feedback
register
sekunde
set
speichern
speicherung
start
support
switch
teil
umsetzung
-
Hallo Lima-Gemeinde,
erstmal an dieser Stelle eine kurze Begrüßung meinerseits
Nun zu meinem eigentlichen Anliegen. Ich programmiere derzeit eine Linear-Feedback-Shift-Register Umsetzung unter C++ und nutze die entstandenen Pseudo-Bits zur OTP-Verschlüsselung.
Nun habe ich das Problem, dass die Generierung der Bits möglichst schnell ablaufen soll und dies durch die Speicherung in einem Container deutlich verlangsamt wird. Als Bsp. erzeuge ich ohne Speicherung der Bits 10.000.000 in durchschnittlich 5 Sekunden.
Mit Speicherung dauert es doppelt so lange. Als Container habe ich bereits das Konkatenieren mit Strings, deque, list, vector und array getestet und keines war vollkommen zufriedenstellend!
Im Endeffekt bin ich nun auf der Suche nach einem Verfahren und meine Bits möglichst schnell in einem Container oder ähnlichem abzuspeichern (Assembler ebenfalls - falls schneller).
Falls gewollt, kann ich noch den SRC-Code dazu präsentieren. Ich hoffe ihr könnt mir helfen
MfG Switch. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
hm. Musst du die gesammten, erzeugten Bits denn ständig hin und her shiften, oder erzeugst du die Bits einfach und dann passiert mit ihren nichts weiter?
Falls letzteres, kannst du doch einfach ein ganz normalen malloc-Speicher anlegen und dort sequenziell die Bits ablegen. -
Danke für deine Antwort, falls kein Verfahren schneller ist werde ich erstmal so vorgehen.
Mir hat sich nun noch eine weitere Frage ergeben - und zwar wüsste ich gerne, ob man die Funktionalität eines bitset auch mit einer anderen Methodik noch performanter umsetzen kann. Hierbei müsste ich shiften können (>>=) und auf die einzelnen Elemente zugreifen können, um das Erste bei jedem Durchlauf zu entnehmen und einige miteinander zu XORen, wobei das Ergebnis auch wieder eingefügt werden muss.
MfG Switch. -
Wenn du wirklich größtenteils binär auf deinen Daten rumarbeitest (bitset, bittest, shift, roll, and, or, xor, not), tut sich die Frage auf, ob das alles in inline-Assembler nicht schneller ablaufen würde. Das hängt aber von der Güte deines Kompilers ab. Wenn der das eh schon für deinen Proz optimiert, wirst du da mit Hand kaum noch mehr rausholen können.
Anderer Ansatz wäre, C++ (mit dem Riesen-Overhead) komplett wegzulassen und direkt alles in asm zu schreiben. Das wäre auf alle Fälle performanter.
Ich selbst habe auch einiges mit (zeitkritischen) Kryptoalgorithmen gearbeitet und der Matchwinner war: eine zweite GraKa. Gib Teile der Berechnungen von der CPU an eine (oder mehrere) GPUs ab, vor allem diejenigen Anteile, die vektoriell sind. -
Also ich bezweifle, dass ich mein gesamtes Vorhaben in ASM umsetzen könnte, da mir dazu auch einfach die nötigen Kenntnisse fehlen.
Inline-Assembler halte ich selber für die zeitkritischen Abläufe auch am Besten, allerdings bin ich in ASM wie gesagt recht unerfahren und habe keine Ahnung, unter welchem Aufwand ich diese kleine "bitset-Umsetzung" programmieren müsste. Als Kompiler verwende ich Visual C++ 2008 und ich denke durch Inline-ASM sollte da noch Einiges möglich sein?
Vielleicht kannst du mir ein Bißchen unter die Arme greifen und einfach mal auf ein Bespiel verweisen oder selber die Erstellung eines linear rückgekoppelten Schieberegisters unter ASM in einem kleinen Code-Aussschnitt deutlich machen
MfG Switch.
PS:
Bevor ich es vergesse, ich wäre sehr erfreut, wenn jemand kurz die korrekte Verwendung von OpenMP zum Support von mehrkernigen CPUs beschreibt. Ich habe es alles korrekt eingebunden und verwende für eine Schleife den Präprozessor-Befehl "#pragma omp parallel for" und trotzdem berechnet er nur mit 50%iger Auslastung( -> 1 Kernig?). Support von GPU würde mich nun auch interessieren
Beitrag zuletzt geändert: 17.8.2009 16:37:29 von sw1tch -
Kann ich gerne machen. Hab schon ewig kein asm mehr gemacht und ein bisschen Übung tut nicht weh. Nur noch eine Frage?
Ist ein linear rückgekoppeltes Schieberegister ein Linear Feedback Shift Register?
EDIT:
Und natürlich wie breit und welches Polynom. . .
Beitrag zuletzt geändert: 17.8.2009 16:31:12 von census -
Danke für die Mühe :)
Zu deinen Fragen: Ja es ist ein Linear Feedback Shift Register und bei dem Polynom handelt es sich um eines mit dem Grad 160. Das primitive Polynom dazu ist x^160 + x^19 + x^18 + x + 1. Wenn du noch meine C++ Umsetzung dazu brauchst, dann nur zu.
MfG Switch.
PS:
Als Seed kannste dir ja einfach welche aussuchen, wenn du doch nen bestimmten willst, dann kann ich dir gerne einen geben.
Beitrag zuletzt geändert: 17.8.2009 16:47:23 von sw1tch -
Hm, ich hab das ganze erstmal in C geschrieben, damit ich weiß was ich tue, bevor ich mit Assembler anfange. Allerdings ist mir etwas seltsames aufgefallen. Du sagst dass du 10.000.000 bits in etwa 5 Sekunden berechnest und 10 Sekunden für Berechnen und Speichern brauchst. Mein Programm berechnet 1.000.000.000 bits (also 100mal soviel) in etwa 5 Sekunden und braucht für Berechnen und Speichern etwa 9 Sekunden. Entweder hab ich nicht ganz verstanden was ein LFSR macht oder dein Code ist etwas ineffizient. Schau dir bitte mal meinen Code an:
#include <stdio.h> #include <time.h> #include <stdlib.h> int main () { unsigned long left; unsigned long center; unsigned long right; unsigned int new; unsigned int count; short *buffer = (short*) malloc (sizeof (short) * 1000000000); left = 0x80000000L; center = 0L; right = 0L; for (count = 0; count < 1000000000; count ++) { buffer [count] = right & 1; new = 1 & (right >> 19 ^ right >> 18 ^ right >> 1 ^ right); right = right >> 1 | center << 63; center = center >> 1 | left << 63; left = left >> 1 | new << 31; } printf ("Terminated in %d ms.\n", (int) (clock () / (CLOCKS_PER_SEC / 1000) ) ); return 0; }
Zur Kontrolle: Bei Startwert 0x8000 0000 0000 0000 0000 0000 0000 0000 0000 0000 (also eine 1 und 159 Nullen) sind das die ersten 1000 bits:
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1100000000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000010100000000000000000000000000000000010100000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000111100000000000000 1111000000000000001111000000000000001111000000000000000000000000000000000000000000000000000000000000 0000000000000000000000010001000000000000000000000000000000000000000000000000000000000000000000010001 0000000000000000000000000000000000000000000000000000000000000000110011000000000000110011000000000000 0000000000000000000000000000000000001100110000000000001100110000000000000000000000000000000000000000
(EDIT: Ich hatte vergessen right und center zu nullen)
Beitrag zuletzt geändert: 17.8.2009 19:20:02 von census -
Ich poste an dieser Stelle schonmal meine Umsetzung, dann kannst du schonmal vergleichen, ob wir der gleichen Idee nachgegangen sind. Ich werde in der Zeit versuchen deinen Code nen bißchen intensiver zu verstehen, da ich noch nicht lange C++ programmiere und dieses Programm mein Einstieg in die Kryptographie ist und gleichzeitig ein bißchen "learning by doing" sein soll
Ich weiß, dass der Code alles andere als gut ist aber es ging mir ersteinmal nur darum, es überhaupt umzusetzen...
bool feed; bool *Cont = new bool[Length*8]; omp_set_num_threads(2); #pragma omp parallel for private(j) for(j = 0; j < Length*8; j++) { if(LFSR_C[0] == true){ Cont[j] = LFSR_1[0]; feed = (((LFSR_1[0] ^ LFSR_1[1]) ^ LFSR_1[18]) ^ LFSR_1[19]); LFSR_1 >>= 1; LFSR_1.set(159, feed); } else { Cont[j] = LFSR_2[0]; feed = (((LFSR_2[0] ^ LFSR_2[1]) ^ LFSR_2[18]) ^ LFSR_2[19]); LFSR_2 >>= 1; LFSR_2.set(159, feed); } feed = (((LFSR_C[0] ^ LFSR_C[1]) ^ LFSR_C[18]) ^ LFSR_C[19]); LFSR_C >>= 1; LFSR_C.set(159, feed); } delete[] Cont;
Edit 1:
Die Speicherung dauert hier nun nicht mehr sonderlich lange (unter 1 Sekunde bei 10 Millionen).
Edit 2:
Code aktualisiert, hatte den falschen erwischt, sorry :/
Edit 3 (nimmt das mal ein Ende?):
Habe nun das Problem mit dem Multi-Core Support gelöst!
Beitrag zuletzt geändert: 17.8.2009 20:15:34 von sw1tch -
Von welchem Typ sind LFSR_C, LFSR_1 und LFSR_2? Scheinen ja Objekte von irgendwelchen Klassen zu sein. Poste mal die Klassendefinition. Der Performance-Verlust liegt wahrscheinlich in der Implementierung dieser Klasse.
Seh ich da was falsch oder sind das drei unabhängige LFSR, wobei 1 und 2 nur dann geshiftet werden, falls das LSB von LFSR_C 0 oder 1 ist?
EDIT: Zum Verständnis: Mein Programm hat genau ein LFSR, das durchläuft. Also so wie deines nur mit LFSR_C.
EDIT2: Mach mal aus
for(j = 0; j < Length*8; j++)
folgendes:
int k = Length*8; for (j = 0; j < k; j++)
so sparst du dir die Multiplikation bei jedem Schleifendurchlauf.
EDIT3:
Ich hab meinen Code angepasst, so dass er dasselbe tut wie deiner:
#include <stdio.h> #include <time.h> #include <stdlib.h> int main () { unsigned long left_C = 0x80000000L; unsigned long center_C = 0L; unsigned long right_C = 0L; unsigned long left_1 = 0x80000000L; unsigned long center_1 = 0L; unsigned long right_1 = 0L; unsigned long left_2 = 0x80000000L; unsigned long center_2 = 0L; unsigned long right_2 = 0L; unsigned int feed; unsigned int length = 10000000; unsigned int length8 = length * 8; unsigned int j; short *buffer = (short*) malloc (sizeof (short) * length8); for (j = 0; j < length8; j ++) { if (right_C & 1) { buffer [j] = right_1 & 1; feed = 1 & (right_1 >> 19 ^ right_1 >> 18 ^ right_1 >> 1 ^ right_1); right_1 = right_1 >> 1 | center_1 << 63; center_1 = center_1 >> 1 | left_1 << 63; left_1 = left_1 >> 1 | feed << 31; } else { buffer [j] = right_2 & 1; feed = 1 & (right_2 >> 19 ^ right_2 >> 18 ^ right_2 >> 1 ^ right_2); right_2 = right_2 >> 1 | center_2 << 63; center_2 = center_2 >> 1 | left_2 << 63; left_2 = left_2 >> 1 | feed << 31; } feed = 1 & (right_C >> 19 ^ right_C >> 18 ^ right_C >> 1 ^ right_C); right_C = right_C >> 1 | center_C << 63; center_C = center_C >> 1 | left_C << 63; left_C = left_C >> 1 | feed << 31; } printf ("Terminated in %d ms.\n", (int) (clock () / (CLOCKS_PER_SEC / 1000) ) ); return 0; }
Bei length=10000000 (also 80 Millionen Durchgängen) braucht er bei mir auf einem Kern 1,1 sec. Bei length= 1250000 (also 10 Millionen Durchgängen) braucht er auf einem Kern 140 ms.
Beitrag zuletzt geändert: 17.8.2009 20:47:17 von census -
Ich generiere von einem eingegebenen Passwort den SHA-1 Hash (40 Zeichen). Nun wandle ich jedes zeichen mithilfe der ASCII-Werte in 8 Bit um und erhalte 320 Bit. Von den 320 Bit werden dann drei verschiedene 160 Bit-Blöcke auf die drei verschiedenen LFSR verteilt und LFSR_C entscheidet, welches der beiden anderen das Output-Bit generiert. Die LFSRs sind einfache bitsets.
Das Prinzip möchte ich in der Art auch behalten, da ein Angriff auf das LFSR unterbunden wird, da der Angreifer nicht weiß aus welchem Schieberegister das Output-Bit kommt und somit nicht die Initialisierungs-Werte herausfinden kann.
MfG Switch.
Beitrag zuletzt geändert: 17.8.2009 20:44:07 von sw1tch -
sw1tch schrieb:
Ich generiere von einem eingegebenen Passwort den SHA-1 Hash (40 Zeichen). Nun wandle ich jedes zeichen mithilfe der ASCII-Werte in 8 Bit um und erhalte 320 Bit. Von den 320 Bit werden dann drei verschiedene 160 Bit-Blöcke auf die drei verschiedenen LFSR verteilt und LFSR_C entscheidet, welches der beiden anderen das Output-Bit generiert. Die LFSRs sind einfache bitsets.
Das Prinzip möchte ich in der Art auch behalten, da ein Angriff auf das LFSR unterbunden wird, da der Angreifer nicht weiß aus welchem Schieberegister das Output-Bit kommt und somit nicht die Initialisierungs-Werte herausfinden kann.
MfG Switch.
Die Zeitangabe "unter 1 Sec bei 10 Millionen" bezieht sich auf length=10000000 (also 80000000 Durchläufe) oder auf length=1250000 (also 10000000 Durchläufe) ? -
Bezieht sich auf 10000000 Durchläufe, allerdings nur die Zeit der Speicherung.
Ich bin dir schonmal zu dank verpflichtet für deine deutlich effizientere Lösung! Allerdings hab ich nun noch eine Frage, wie initialisiere ich nun die LFSR korrekt mit meinen Werte?
Als Bsp. hierzu habe ich als Hash "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" (von "test").
Die ersten 160 Bit, wie aus den ASCII-Werten hervor geht:
0110000100111001001101000110000100111000011001100110010100110101011000110110001101100010001100010011100101100010011000010011011000110001011000110011010001100011
Diese möchte ich nun als Seed für LFSR_1 verwenden, also müsste ich ja dementsprechend left_1 editieren... nur wie?
MfG Switch. -
sw1tch schrieb:
Bezieht sich auf 10000000 Durchläufe, allerdings nur die Zeit der Speicherung.
Ich bin dir schonmal zu dank verpflichtet für deine deutlich effizientere Lösung! Allerdings hab ich nun noch eine Frage, wie initialisiere ich nun die LFSR korrekt mit meinen Werte?
Als Bsp. hierzu habe ich als Hash "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" (von "test").
Die ersten 160 Bit, wie aus den ASCII-Werten hervor geht:
0110000100111001001101000110000100111000011001100110010100110101011000110110001101100010001100010011100101100010011000010011011000110001011000110011010001100011
Diese möchte ich nun als Seed für LFSR_1 verwenden, also müsste ich ja dementsprechend left_1 editieren... nur wie?
MfG Switch.
Versteh ich nicht, wenn dein Hash 0xa948fe.... ist, dann sind die ersten bits doch die folgenden oder nicht???
1010 1001 0100 1000 1111 1110
Warum interpretierst du die ASCII einer Hexzahl? Das macht deinen Seed ja sehr schwach, weil dieselben 16 verschiedenen 8-Bit-Folgen (nämlich die Ziffern 0-9 und die Buchstaben a-f) immer wiederkommen. . . Ich glaube dieses Key Expansion Scheme ist ein bisschen schwach auf der Brust. -
Im Prinzip hast du Recht, doch ist das nicht irrelevant wenn der Seed eh nicht zutage kommt? Dieser ist ja durch das verwenden von 3 Schieberegistern geschützt und somit nicht von einem Angriff bedroht.
Ansonsten habe ich meinen Fehler schon bemerkt :)
MfG Switch.
Edit:
Da scheint mir etwas nicht plausibel. Ich habe folgende Seeds verwendet:
unsigned long left_C = 12198720757830859000; bzw. 0xa94a8fe5ccb19ba6L
unsigned long left_1 = 15245222982208932000; bzw. 0xd391e987982fbbd3L
unsigned long left_2 = 15245222982208932000;
und erhalte diese ersten 100 Bits:
0000000000000000000000000000000000000000000000000000000000000000000000000010000100000010000010001111
Eig. sollte LFSR_C doch so aussehen:
1010100101001010100011111110010111001100101100011011100011010110
LFSR_1 und LFSR_2 dementsprechend:
1101001110010001111010011000011110011000001011111010010111101011
Ich glaube ich brauch erstmal ne Pause und werde später nochmal mit klarem Kopf das Ganze überdenken, man dürfe mich gerne auf meinen Denkfehler aufmerksam machen...
Beitrag zuletzt geändert: 17.8.2009 22:21:58 von sw1tch -
Du musst die 160 bits wie folgt verteilen, falls du sie z.B. nach LFSR_C laden willst:
left_C = 32 Nullen und die bits 0 bis 31
center_C = bits 32 bis 95
right_C bits 96 bis 159
Dann klappts auch mit dem Nachbarn ^^
So ich hab da mal was in Assembly vorbereitet:
1.000.000.000 Durchläufe in 3,4 Sekunden mit Speichern, aber nur einem Register. Grob doppelt so schnell wie die C-Variante:
#include <stdio.h> #include <time.h> #include <stdlib.h> unsigned long left = 0x80000000L; unsigned long center = 0L; unsigned long right = 0L; unsigned long length = 1000000000L; unsigned int j; char *buffer; int main () { buffer = (char*) malloc (length); asm ("mov rsi,buffer\n"); asm ("mov rdi,length\n"); asm ("dec rdi\n"); asm ("mov rbx,left\n"); asm ("mov rcx,center\n"); asm ("mov rdx,right\n"); asm ("start:\n"); asm ("mov r8,rdx\n"); asm ("shr r8,1\n"); asm ("setc al\n"); asm ("mov byte ptr [rsi],al\n"); asm ("inc rsi\n"); asm ("mov rax,rdx\n"); asm ("xor rax,r8\n"); asm ("shr r8,17\n"); asm ("xor rax,r8\n"); asm ("shr r8,1\n"); asm ("xor rax,r8\n"); asm ("and rax,1\n"); asm ("mov r8,rcx\n"); asm ("shl r8,63\n"); asm ("shr rdx,1\n"); asm ("or rdx,r8\n"); asm ("mov r8,rbx\n"); asm ("shl r8,63\n"); asm ("shr rcx,1\n"); asm ("or rcx,r8\n"); asm ("shl rax,31\n"); asm ("shr rbx,1\n"); asm ("or rbx,rax\n"); asm ("dec rdi\n"); asm ("jnz start\n"); for (j = 0; j < 1000; j++) printf ("%d%s", buffer [j], j % 100 - 99 ? "" : "\n" ); printf ("Terminated in %d ms.\n", (int) (clock () / (CLOCKS_PER_SEC / 1000) ) ); return 0; }
Beitrag zuletzt geändert: 17.8.2009 22:43:13 von census -
Tausend dank!
Halt dich bereit, falls noch Fragen aufkommen, da ich bestimmt wieder irgendwas nicht verstehe
MfG Switch. -
Ich habe noch mal ein bisschen über deine drei LFSR nachgedacht. Das Register C wird immer weitergeschoben und dessen Ausgabe legt fest, ob Register A oder Register B weitergeschoben werden und somit die effektive Ausgabe liefern.
Ich kann zwar mathematisch noch nicht ganz den Finger darauflegen, aber ich hab es im Urin, dass du dadurch nichts gewinnst. Ich habe das Gefühl, dass sich dieses Konstrukt auch durch ein einziges Register realisieren lässt, denn die Konkatenierung zweier Polynome ist ja auch immer noch ein Polynom. Ich werde heute mal unsere Informationstechniker überfallen und schauen, ob ich einen Mathematiker damit belästigen kann. -
Meiner Meinung nach sind mindestens 2 LFSR nötig, da ein Register einem Know-plaintext Angriff doch ausgesetzt wäre.
Angenommen der Angreifer kennt die Länge des Registers (bspw. durch reverse engineering meines Tools) und eine Folge von Klartext-Bits (und dazu dann natürlich die Geheimtext-Bits). Nun kann er daraus die Output-Bits ermittteln und das LFSR ist geknackt.
Verwendet man nun mindestens 2 LFSR, dann kann er zwar genauso vorgehen, weiß aber nicht, aus welchem Register das Output-Bit stammt und kann somit nicht die entsprechenden Seeds ermitteln.
Wobei hier gesagt werden muss, dass - wenn man 2 LFSR verwendet - das Verfahren natürlich anders abläuft (z.B. XORed man beide Output-Bits miteinander und erhält das "finale" Bit. Der Angreifer weiß zwar (auch wieder durch reverse engineering), dass die beiden Output-Bits miteinander geXORed werden und kann somit deren Zustände rekonstruieren, doch weiß er nicht welchem Register er welches Bit zuordnen soll.
Ich hoffe ich hab da keinen Denkfehler drin, aber demnach müsste die Verwendung von einem Register nicht sicher sein.
MfG Switch.
PS:
ich meine ich hätte in einem anderen Thread mal gelesen, dass du Kryptologie (oder in der Richtung) studiert hast, da müssten doch LFSR im Bezug auf PRNG bzw. CSPRNG behandelt worden sein?
PPS:
Kurze Nachfrage:
Bei Hash("test") = a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 sollte doch dieser Code korrekt sein (?):
unsigned long left_C = 0x00000000a94a8fe5L; // ist doch equivalent zu 0xa94a8fe5L ? unsigned long center_C = 0xccb19ba61c4c0873L; unsigned long right_C = 0xd391e987982fbbd3L;
Dann kann ich doch auch die Werte einfachheitshalber zur Basis 10 anstatt 16 angeben:
unsigned long left_C = 2840236005; unsigned long center_C = 14749741392356678000; unsigned long right_C = 15245222982208932000;
Nun ist unsigned long ja ein 32bit Datentyp mit maximaler Größe 4.294.967.295. Ich bräuchte aber doch Speicher für 64bit, müsste also einen long long Datentyp verwenden, oder täusche ich mich?
PPPS:
Habe nun mal (versucht) den ASM-Code in meinem C++ Projekt einzubinden und habs mit folgender C++ konformer Syntax gemacht:
Zum Thema korrekte Einbindung: http://msdn.microsoft.com/en-us/library/45yd4tzz%28VS.80%29.aspx
inline void ASM_LFSR() { unsigned long left = 0x80000000L; unsigned long center = 0L; unsigned long right = 0L; unsigned long length = 1000000000L; unsigned int j; char *buffer; buffer = (char*) malloc (length); __asm mov rsi, buffer __asm mov rdi, length __asm dec rdi __asm mov rbx,left __asm mov rcx,center __asm mov rdx,right [...]
Als Fehler-Code erhalte ich nun: "improper operand type" bzw. bei dem 2. Assembly-Befehl "inline assembler syntax error in 'second operand'"
Irgendwelche Ideen, Googol hat nicht viel ergeben.
Beitrag zuletzt geändert: 18.8.2009 17:14:44 von sw1tch -
OK, ich habe das ganze unter Linux 64-bit mit gcc kompiliert. Dort ist unsigned long ein 64-bit Integer (hab nen 64-bit quadcore). Mach mal jeweils aus "unsigned long" ein "unsigned int64" oder ein "ULONGLONG", hoffentlich hilft das.
Das ganze musst du natürlich auch auf einem 64-bit-System kompilieren, assemblieren, linken und ausführen. Hast du evtl ein 32-bit Windows?
EDIT:
Desweiteren hast du dich zweimal verrechnet:
0xccb19ba61c4c0873 = 14749741392356706419
0xd391e987982fbbd3 = 15245222982208961491
(wenn die Hexzahl auf 73 oder d3 endet, kann die Dezzahl ja schlecht auf 000 enden)
Beitrag zuletzt geändert: 18.8.2009 22:00:17 von census -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage