MD5
-
Hallo hat mal wer versucht den MD5 Alogrithmus nach zu bauen ?
http://de.wikipedia.org/wiki/Message-Digest_Algorithm_5
Und bringt der Pseudo Code hier was ??
// Beachte: Alle Variablen sind vorzeichenlose 32 Bit-Werte und // verhalten sich bei Berechnungen kongruent (≡) modulo 2^32 // Definiere r wie folgt: var int[64] r, k r[ 0..15] := {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22} r[16..31] := {5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20} r[32..47] := {4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23} r[48..63] := {6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21} // Verwende den binären Vorkommateil vom 2^32-fachen Betrag des Sinus // von Integerwerten als Konstanten: für alle i von 0 bis 63 k[i] := floor(abs(sin(i + 1)) × 2^32) // Initialisiere die Variablen: (lt. RFC 1321) var int h0 := 0x67452301 var int h1 := 0xEFCDAB89 var int h2 := 0x98BADCFE var int h3 := 0x10325476 // Vorbereitung der Nachricht 'message': var int message_laenge := bit_length(message) erweitere message um bit "1" erweitere message um bits "0" bis Länge von message in bits ≡ 448 (mod 512) erweitere message um message_laenge als 64-Bit little-endian Integer // Verarbeite die Nachricht in aufeinander folgenden 512-Bit Blöcken: für alle 512-Bit Block von message unterteile Block in 16 32-bit little-endian Worte w(i), 0 ≤ i ≤ 15 // Initialisiere den Hash-Wert für diesen Block: var int a := h0 var int b := h1 var int c := h2 var int d := h3 // Hauptschleife: für alle i von 0 bis 63 wenn 0 ≤ i ≤ 15 dann f := (b and c) or ((not b) and d) g := i sonst wenn 16 ≤ i ≤ 31 dann f := (b and d) or (c and (not d)) g := (5×i + 1) mod 16 sonst wenn 32 ≤ i ≤ 47 dann f := b xor c xor d g := (3×i + 5) mod 16 sonst wenn 48 ≤ i ≤ 63 dann f := c xor (b or (not d)) g := (7×i) mod 16 wenn_ende temp := d d := c c := b b := ((a + f + k(i) + w(g)) leftrotate r(i)) + b a := temp // Addiere den Hash-Wert des Blocks zur Summe der vorherigen Hashes: h0 := h0 + a h1 := h1 + b h2 := h2 + c h3 := h3 + d var int digest := h0 append h1 append h2 append h3 //(Darstellung als little-endian)
-
Auf der Wiki-Seite gibt es doch auch einen Link mit C++ Beispielcode.
-
hab ihn nachgebaut und das kam raus:
md5sum.cpp
#include "md5sum.hpp" #include <sstream> #include <vector> #include <cmath> md5sum::md5sum(void) { calculate_checksum(""); } md5sum::md5sum(__in const std::string& data) { calculate_checksum(data); } md5sum::md5sum(__in const BYTE *data, __in unsigned int len) { calculate_checksum(data, len); } md5sum::md5sum(__in const std::ifstream& data) { calculate_checksum(data); } void md5sum::calculate_checksum(__in const BYTE *data, __in unsigned int len) { // Daten in korrektes Format bringen const unsigned int length = len; std::vector<BYTE> vData(length); for (unsigned int n = 0; n < length; ++n) vData[n] = data[n]; vData.push_back(128); while ((vData.size() + 8) % 64) vData.push_back(0); unsigned __int64 iSizeInBits = length * 8; BYTE *pLength = reinterpret_cast<BYTE*>(&iSizeInBits); for (int n = 0; n < 8; ++n) vData.push_back(pLength[n]); // Konstanten definieren h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476; const DWORD r[64] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }; DWORD k[64]; for (int n = 0; n < 64; ++n) k[n] = static_cast<DWORD>(floor(abs(sin(static_cast<double>(n + 1))) * (pow(static_cast<double>(2), 32)))); // Aufteilung unsigned __int64 iFullSize = static_cast<unsigned __int64>(vData.size()); unsigned __int64 iNumParts = iFullSize / 64; // Verarbeitung for (unsigned __int64 n = 0; n < iNumParts; ++n) { // Hash-Wert initialisieren DWORD a = h0, b = h1, c = h2, d = h3; DWORD f = 0, g = 0; // in 16 32-Bit Worte unterteilen union { BYTE bValues[64]; DWORD dwValues[16]; } Part; for (int i = 0; i < 64; ++i) Part.bValues[i] = vData[i + static_cast<int>(n * 64)]; // Hauptschleife for (int i = 0; i < 64; ++i) { if ((i >= 0) && (i <= 15 )) { f = (b & c) | ((~b) & d); g = i; } else if ((i >= 16) && (i <= 31)) { f = (b & d) | (c & (~d)); g = ((5 * i) + 1) % 16; } else if ((i >= 32) && (i <= 47)) { f = b ^ c ^ d; g = ((3 * i) + 5) % 16; } else { f = c ^ (b | (~d)); g = (7 * i) % 16; } DWORD temp = d; d = c; c = b; b = _lrotl((a + f + k[i] + Part.dwValues[g]), r[i]) + b; a = temp; } // Hashwerte addieren h0 += a; h1 += b; h2 += c; h3 += d; } } void md5sum::calculate_checksum(__in const std::string& data) { md5sum::calculate_checksum(reinterpret_cast<const BYTE*>(data.c_str()), data.length()); } void md5sum::calculate_checksum(__in const std::ifstream& data) { std::ifstream &rData = const_cast<std::ifstream&>(data); rData.seekg(0, std::ios::end); unsigned int size = rData.tellg(); rData.seekg(0); BYTE *pData = new BYTE[size]; rData.read(reinterpret_cast<char*>(pData), size); rData.seekg(0); calculate_checksum(pData, size); delete[] pData; } std::string md5sum::digest(void) { // Checksumme zusammensetzen std::stringstream digest; digest << std::hex; union { BYTE bValues[4]; DWORD dwValue; } h; // DWord 1 h.dwValue = h0; BYTE tmp = h.bValues[0]; h.bValues[0] = h.bValues[3]; h.bValues[3] = tmp; tmp = h.bValues[1]; h.bValues[1] = h.bValues[2]; h.bValues[2] = tmp; digest << h.dwValue; // DWord 2 h.dwValue = h1; tmp = h.bValues[0]; h.bValues[0] = h.bValues[3]; h.bValues[3] = tmp; tmp = h.bValues[1]; h.bValues[1] = h.bValues[2]; h.bValues[2] = tmp; digest << h.dwValue; // DWord 3 h.dwValue = h2; tmp = h.bValues[0]; h.bValues[0] = h.bValues[3]; h.bValues[3] = tmp; tmp = h.bValues[1]; h.bValues[1] = h.bValues[2]; h.bValues[2] = tmp; digest << h.dwValue; // DWord 4 h.dwValue = h3; tmp = h.bValues[0]; h.bValues[0] = h.bValues[3]; h.bValues[3] = tmp; tmp = h.bValues[1]; h.bValues[1] = h.bValues[2]; h.bValues[2] = tmp; digest << h.dwValue; // Resultat zurückgeben return digest.str(); }
md5sum.hpp
#pragma once #include <Windows.h> #include <string> #include <fstream> class md5sum { private: DWORD h0, h1, h2, h3; void calculate_checksum(__in const BYTE *data, __in unsigned int len); void calculate_checksum(__in const std::string& data); void calculate_checksum(__in const std::ifstream& data); public: md5sum(void); md5sum(__in const BYTE *data, __in unsigned int len); md5sum(__in const std::string& data); md5sum(__in const std::ifstream& data); std::string digest(void); }; #define MD5(data) md5sum(data).digest().c_str()
-
und als kleines Beispielprog:
#include <iostream> #include <fstream> #include "md5sum.hpp" int main(int argc, char** argv) { std::cout << "md5sum Version 1.0" << std::endl; std::cout << "Copyright (C) 2009, Drako" << std::endl; std::cout << std::endl; if (argc != 2) { std::cout << "Usage: md5sum [filename|string]" << std::endl; return 0; } std::ifstream inFile(argv[1], std::ios::in | std::ios::binary); if (!(inFile.is_open())) { std::cout << "String: " << argv[1] << std::endl; std::cout << "MD5 Hash: " << md5sum(argv[1]).digest() << std::endl; } else { std::cout << "Filename: " << argv[1] << std::endl; std::cout << "MD5 Hash: " << md5sum(inFile).digest() << std::endl; } return 0; }
das ganze liefert korekte ergebnisse (zumindest soweit ich es getestet habe),
weshalb ich einfach mal davon ausgehe, dass ich es korrekt implementiert habe
-
Ehm, ja? Fragen? Probleme? Oder war das einfach für dein Mitteilungsbedürfnis?
-
@DrakoXP: Vielen Dank
-
xD no problem^^
hab wohl übersehen, dass das noch von 2008 war
-
das wär sicher auch mal was interessantes fürs Magazin,
verschiedene Implentationen von Hash-Algorithmen, die man dann auch leicht einbauen kann.ich beispielsweise habe vergebens im Netz nach einer Lib gesucht, in der ich einfach
string hash = MD5("hallo welt");
eingeben kann.
bevor ich mich rangesetzt habe und die Wikipedia-Variante nachgebaut habe,
verwendete ich auch mal OpenSSL um MD5-Hashes zu generieren, aber selbst das war
mehr als ein simpler Funktions/Makro-Aufruf.
-
Unter Linux gibt es md5sum als Miniprogramm, Sourcen sollten auch verfuegbar sein. Desweiteren habe ich im Netz z.B. http://256.com/sources/md5/ gefunden und vieles mehr.
-
mist. so schöner code und ich habe gerade wegen http://www.mathstat.dal.ca/~selinger/md5collision/ die lust an md5 verloren.