MD5

  • Der folgende Quellcode ist eine BCB-Abwandlung des MD5 Message Digest Algorithm zum Codieren von Strings mittels MD5 Checksummen.
  • Verwendung:
#include "md5.h";

...

MD5Obj *pMD5 = new MD5Obj();

// MD5-Hash eines Strings
AnsiString sInput = "abc"; //MD5 Hash: 900150983cd24fb0d6963f7d28e17f72
AnsiString sTest = pMD5->MD5_CheckString(sInput);

// MD5-Hash einer Datei
int iFileSize;
int iFileHandle;
int iBytesRead;
char *pchTemp;
AnsiString sMD5Str = "";

iFileHandle = FileOpen(sInput.c_str(), fmShareDenyWrite);

if (iFileHandle)
{
  iFileSize = FileSeek(iFileHandle, 0, 2);
  FileSeek(iFileHandle, 0, 0);

  pchTemp = new char[iFileSize+1];

  iBytesRead = FileRead(iFileHandle, pchTemp, iFileSize);

  if (iBytesRead == iFileSize) sMD5Str = pMD5->MD5_CheckFile(pchTemp, iFileSize);

  delete[] pchTemp;

  FileClose(iFileHandle);
}

if (pMD5) delete pMD5;
  • md5.h
#ifndef MD5_H
#define MD5_H
#ifdef __alpha
typedef unsigned int uint32;
#else
typedef unsigned long uint32;
#endif

#include <vcl.h>

struct MD5Context
{
    uint32 buf[4];
    uint32 bits[2];
    unsigned char in[64];
};

class MD5Obj
{
    public:

    MD5Obj(){};
    void MD5Init(struct MD5Context *ctx);
    void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len);
    void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
    void MD5Transform(uint32 buf[4], uint32 in[16]);
    AnsiString MD5_CheckString(AnsiString sInputString);
    AnsiString MD5_CheckFile(char *cpFileData, int iLength);
};

typedef struct MD5Context MD5_CTX;

#endif
  • md5.cpp
// A Borland C++ implementation of the RSA Data Security, Inc. MD5 Message Digest Algorithm, as defined in RFC 1321.

#include "stdio.h"
#include <string.h>
#include "md5.h"
#ifdef sgi
#define HIGHFIRST
#endif

#ifdef sun
#define HIGHFIRST
#endif

#ifndef HIGHFIRST 
#define byteReverse(buf, len)
#else

void byteReverse(unsigned char *buf, unsigned longs)
{
    uint32 t;

    do
    {
        t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | ((unsigned) buf[1] << 8 | buf[0]);

        *(uint32 *) buf = t;
        buf += 4;

    } while (--longs);
}

#endif

#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

#define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
//---------------------------------------------------------------------------
void MD5Obj::MD5Init(struct MD5Context *ctx)
{
    ctx->buf[0] = 0x67452301;
    ctx->buf[1] = 0xefcdab89;
    ctx->buf[2] = 0x98badcfe;
    ctx->buf[3] = 0x10325476;
    ctx->bits[0] = 0;
    ctx->bits[1] = 0;
}
//---------------------------------------------------------------------------
void MD5Obj::MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len)
{
    uint32 t;
    t = ctx->bits[0];

    if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) ctx->bits[1]++;

    ctx->bits[1] += len >> 29;
    t = (t >> 3) & 0x3f;

    if (t)
    {
        unsigned char *p = (unsigned char *) ctx->in + t;
        t = 64 - t;

        if (len < t)
        {
            memcpy(p, buf, len);
            return;
        }

        memcpy(p, buf, t);
        byteReverse(ctx->in, 16);

        MD5Transform(ctx->buf,(uint32*)ctx->in);

        buf += t;
        len -= t;
    }

    while (len >= 64)
    {
        memcpy(ctx->in, buf, 64);
        byteReverse(ctx->in, 16);

        MD5Transform(ctx->buf, (uint32 *) ctx->in);

        buf += 64;

        len -= 64;
    }

    memcpy(ctx->in, buf, len);
}
//---------------------------------------------------------------------------
void MD5Obj::MD5Final(unsigned char digest[16], struct MD5Context *ctx)
{
    unsigned count;
    unsigned char *p;

    count = (ctx->bits[0] >> 3) & 0x3F;
    p = ctx->in + count;
    *p++ = 0x80;
    count = 64 - 1 - count;

    if (count < 8)
    {
        memset(p, 0, count);
        byteReverse(ctx->in, 16);

        MD5Transform(ctx->buf, (uint32 *) ctx->in);

        memset(ctx->in, 0, 56);
    }
    else
    {
        memset(p, 0, count - 8);
    }

    byteReverse(ctx->in, 14);

    ((uint32 *) ctx->in)[14] = ctx->bits[0];
    ((uint32 *) ctx->in)[15] = ctx->bits[1];


    MD5Transform(ctx->buf,(uint32 *) ctx->in);

    byteReverse((unsigned char *) ctx->buf, 4);

    memcpy(digest, ctx->buf, 16);
    memset(ctx, 0, sizeof(ctx));
}
//---------------------------------------------------------------------------
void MD5Obj::MD5Transform(uint32 buf[4], uint32 in[16])
{
    register uint32 a, b, c, d;
    a = buf[0];
    b = buf[1];
    c = buf[2];
    d = buf[3];

    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);

    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 
    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 
    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 
    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 
    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 
    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 
    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 
    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 
    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 
    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 
    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 
    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 
    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 
    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 

    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 
    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 
    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 
    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 
    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 
    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 
    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 
    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 
    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 
    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 
    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 
    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 
    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 
    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 
    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 
    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 

    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 
    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 
    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 
    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 
    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 
    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 
    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 
    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 
    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 
    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 
    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 
    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 
    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 
    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 
    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 
    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 

    buf[0] += a; 
    buf[1] += b; 
    buf[2] += c; 
    buf[3] += d;
}
//--------------------------------------------------------------------------- 
AnsiString MD5Obj::MD5_CheckString(AnsiString sInputString)
{
    struct MD5Context ctx;
    char *password = sInputString.c_str();
    unsigned char digest[16];

    MD5Init (&ctx);
    MD5Update (&ctx, password, strlen(password));
    MD5Final (digest, &ctx);
    char tmp[33];

    for (int s=0; s<16; s++) sprintf (&tmp[s+s], "%02x", digest[s]);

    AnsiString sRetStr = tmp;

    return sRetStr;
}
//---------------------------------------------------------------------------
AnsiString MD5Obj::MD5_CheckFile(char *cpFileData, int iLength)
{
    struct MD5Context ctx;
    unsigned char digest[16];

    MD5Init (&ctx);
    MD5Update (&ctx, cpFileData, iLength);
    MD5Final (digest, &ctx);
    char tmp[33];

    for (int s=0; s<16; s++) sprintf (&tmp[s+s], "%02x", digest[s]);

    AnsiString sRetStr = tmp;

    return sRetStr;
}

ROT 13

// Prinzip: Da das Alphabet 26 Buchstaben hat, kann durch einfache Rotation
// der Buchstaben um 13 Stellen ein Text unleserlich gemacht werden.
// Mit dem selben Algorithmus ist es dann auch wieder möglich,
// den so chiffrierten Text wieder zu dekodieren.
// Es werden hierbei nur die Buchstaben rotiert,
// keine Zahlen und Sonderzeichen.
void rot13(char *string)
{
    int len = strlen(string), x;

    for (x = 0; x <= len; x++)
    {
        if (((string[x] >= 65) && (string[x] <= 77)) || ((string[x] >= 97) && (string[x] <= 109)))
        {
            printf("%c", string[x]+13);
        }
        else if (((string[x] >= 78) && (string[x] <= 90)) || ((string[x] >= 110) && (string[x] <= 122)))
             {
                printf("%c", string[x]-13);
             }
             else printf("%c",string[x]);
    }
}

Beispiel für die Arbeit mit dem ValueListEditor

// es werden 4 Buttons, 1 ValueListEditor und 1 Edit benötigt

// *.h
private: // Anwender-Deklarationen
TStringList *berufe;

...

// *.cpp: 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    // VLE schön machen :)
    ValueListEditor1->DisplayOptions << doColumnTitles << doAutoColResize;
    ValueListEditor1->TitleCaptions->Strings[0] = "Vorname";
    ValueListEditor1->TitleCaptions->Strings[1] = "Beruf";

    // StringList für die im VLE angezeigte ComboBox (PickList) vorbereiten:
    berufe = new TStringList();
    berufe->Add("Bäcker");
    berufe->Add("Angler");
    berufe->Add("Psychater");
    berufe->Add("Informatiker");
    berufe->Sort();

    Edit1->Text = "Emil";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    // die StringList muss natürlich auch wieder weg
    delete berufe;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // neues Wertepaar in den VLE einsetzen
    ValueListEditor1->InsertRow(Edit1->Text, "", false);

    // Picklist für das Wertefenster erstellen
    ValueListEditor1->ItemProps[ValueListEditor1->Row-1]->EditStyle = esPickList;
    ValueListEditor1->ItemProps[ValueListEditor1->Row-1]->PickList = berufe;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    // gewählte Zeile im VLE löschen
    if (ValueListEditor1->Strings->Count > 0) ValueListEditor1->DeleteRow(ValueListEditor1->Row);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
    // gewählte Zeile im VLE ändern
    if (ValueListEditor1->Strings->Count > 0) ValueListEditor1->Keys[ValueListEditor1->Row] = Edit1->Text;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
    // VLE speichern
    if (ValueListEditor1->Strings->Count > 0) ValueListEditor1->Strings->SaveToFile("./Test.dat");
}

Treeview-Item unter dem Mauscursor ermitteln

void __fastcall TForm1::TreeView1DblClick(TObject *Sender)
{
    TPoint P = Mouse->CursorPos;
    P = MenuTreeView->ScreenToClient(P);

    THitTests HT = MenuTreeView->GetHitTestInfoAt(P.x,P.y);
    TTreeNode *pItem = MenuTreeView->GetNodeAt(P.x,P.y);

    if (HT.Contains(htOnItem) || HT.Contains(htOnIcon))
    {
        AnsiString S = AnsiString("Item an Position ") + AnsiString(pItem->Level);
        ShowMessage(S);
    }
}

verschiedene Hints in einem Treeview anzeigen

void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
    Application->ShowHint = true;
    Application->OnShowHint = DoShowHint;
    Application->HintPause = 10;
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::DoShowHint(System::AnsiString &HintStr, bool &CanShow, THintInfo &HintInfo)
{
    if (HintInfo.HintControl->ClassNameIs("TTreeView"))
    {
        HintInfo.HintMaxWidth = 200;
        HintInfo.HintPos.x += 10;
        HintInfo.ReshowTimeout = 50;
    }
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::TreeViewMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
    if (Sender->ClassNameIs("TTreeView"))
    {
        TTreeNode *Node;
        Node = ((TTreeView*)Sender)->GetNodeAt(X, Y);

        if (Node == NULL)
        {
            ((TTreeView*)Sender)->ShowHint = false;
        }
        else
        {
            ((TTreeView*)Sender)->Hint = Node->Text;
            ((TTreeView*)Sender)->ShowHint = true;
        }
    }
}

In einem TreeView TreeNode->Data eine Struktur zuweisen

// erst ein Struct definieren
struct BeispielStruct
{
    AnsiString BeispielString;
    int iZahl;
}

// Struct dem TTreeNode zuweisen 
BeispielStruct* Test = new BeispielStruct;
Test->BeispielString = "Test";
Test->iZahl = 5;
TreeNode->Data = (void*)Test;

// Aufruf 
if (TreeNode->Data)
{
    BeispielStruct *Test = (BeispielStruct*)TreeNode->Data;
    ShowMessage(Test->BeispielString);
}

// Beim Beenden delete der einzelnen in TreeNode->Data gespeicherten Structe nicht vergessen! 

Drag & Drop verwenden

// Im Beispiel wird ein Element (Node) aus einem Treeview in ein Listview gezogen
//
// Quelle: Node auf Level 1 (1. Unterverzweigung) eines Treeviews "tvDatapoints"
// DragCursor: crDrag
// DragKind: dkDrag
// DragMode: dmAutomatic
//
// Ziel: Listview "lvInputs" Spalte 1 (Caption von TListItem)
//
// DragCursor: crDrag
// DragKind: dkDrag
// DragMode: dmManual
//
// akzeptiert das Ziel überhaupt das Element unter der Maus?
void __fastcall Form1::lvInputsDragOver(TObject *Sender, TObject *Source, int X, int Y, TDragState State, bool &Accept)
{
     bool bAccept = false;

     TTreeView* pTV = dynamic_cast<TTreeView*->(Source);

     if (pTV)
     {
        bAccept = (pTV->Selected->Level == 1); // z.B. nur wenn Node-Level == 1
     }

     Accept = bAccept;
}
// Zuordnung des akzeptierten Elements im Zielobjekt
void __fastcall Form1::lvInputsDragDrop(TObject *Sender, TObject *Source, int X, int Y)
{
     TTreeView* pTV = dynamic_cast<TTreeView*->(Source);

     if (pTV)
     {
        TTreeNode *pSelNode  = pTV->Selected; // Quelle
        TListItem *pListItem = lvInputs->GetItemAt(X, Y); // Ziel

        if (pSelNode && pListItem)
        {
           pListItem->Caption = pSelNode->Text;
        }
     }
}

BIOS Seriennummer mit WMI auslesen (Win32_BIOS-Klasse)

AnsiString GetBiosSerialNum()
{
    AnsiString ret;
    CoInitializeEx(0, COINIT_MULTITHREADED) ;
    CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);

    IWbemLocator *t_Locator = NULL ;
    HRESULT t_Result = CoCreateInstance (CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IID_IUnknown, ( void ** ) & t_Locator);

    if ( SUCCEEDED ( t_Result ) )
    {
        BSTR t_Namespace = SysAllocString ( L"rootcimv2" ) ;
        if ( t_Namespace )
        {
            IWbemServices *t_Service = NULL ;
            t_Result = t_Locator->ConnectServer (t_Namespace, NULL, NULL, NULL, 0, NULL, NULL, &t_Service) ;

            if ( SUCCEEDED ( t_Result ) )
            {
                // die Property "SerialNumber" der Klasse "Win32_BIOS" auslesen
                BSTR t_Query = SysAllocString ( L"SELECT SerialNumber FROM Win32_BIOS" );
                BSTR t_QueryLanguage = SysAllocString ( L"WQL" );

                if ( t_Query && t_QueryLanguage )
                {
                    // Query starten
                    IEnumWbemClassObject *t_Enumeration = NULL ;
                    t_Result = t_Service->ExecQuery (t_QueryLanguage, t_Query, 0, NULL, & t_Enumeration);

                    // wenn Query erfolgreich
                    if ( SUCCEEDED ( t_Result ) )
                    {
                        t_Enumeration->Reset ();
                        IWbemClassObject *t_ClassObject = NULL;
                        ULONG t_Count = 0;

                        while ( t_Enumeration->Next ( INFINITE, 1, &t_ClassObject, &t_Count ) == WBEM_NO_ERROR )
                        {
                            BSTR t_PropertyName = NULL;
                            CIMTYPE t_CimType;
                            VARIANT t_Variant;
                            VariantInit ( & t_Variant );

                            t_ClassObject->BeginEnumeration ( WBEM_FLAG_NONSYSTEM_ONLY );

                            // alle von der Query angeforderten Properties der Klasse durchgehen
                            while ( t_ClassObject->Next ( 0, &t_PropertyName, &t_Variant, &t_CimType, NULL ) == WBEM_NO_ERROR )
                            {
                                // String zusammenbauen
                                ret += t_Variant.bstrVal;
                                SysFreeString ( t_PropertyName );
                                VariantClear ( & t_Variant );
                            }

                            t_ClassObject->Release ();
                        }

                        t_Enumeration->Release ();
                    }
                }

                SysFreeString ( t_Query );
                SysFreeString ( t_QueryLanguage );
            }

            t_Service->Release ();
            SysFreeString ( t_Namespace );
        }
    }

    t_Locator->Release () ;

    return ret;
}

Opendialog-Multiselect

OpenDialog->Options = OpenDialog->Options <<  ofAllowMultiSelect;

if (OpenDialog->Execute())
{
    // selektierte Files einer Listbox hinzufügen
    ListBox->Items->Text = ListBox->Items->Text + OpenDialog->Files->Text;
}