[C++} Suma kontrolna pierwszych 10 MB pliku

0

Witam
Potrzebuje wykonać sumę kontrolną pierwszych 10 MB pliku.
Znalazłem kod w c#
[C#]Md5 sum

ale nie wiem jak zmodyfikować go do c++, bo tam jest byte[] a jak się orientuje to w C++ nie ma tego.

0

Zamiast byte możesz użyc char i zrobić z tego tablicę.

0

Powiadasz nie ma? A co powiesz na to http://www.example-code.com/vcpp/bytearray.asp ? :P

0

Doszedłem do czegoś takiego

Kod c#:

 FileStream inputFile = new FileStream(@"G:\input.bin", FileMode.Open);
 
            long len = (10 * 1024 * 1024);
            byte[] inputData = new byte[len];
 
            inputFile.Read(inputData, 0, inputData.Length);
 
            byte[] outputData = CryptographyHelper.ComputeMD5(inputData);
 
            Console.WriteLine(CryptographyHelper.ToHexString(outputData));

To po przerobieniu:

 fstream inputFile;
	inputFile.open ("G://input.bin",inputFile.binary|inputFile.in);

 
            long len = (10 * 1024 * 1024);
            unsigned char inputData[] = {len};
 
            inputFile.Read(inputData, 0, inputData.Length); //tu mam problem, nie chce mi się skompilować, dostaje taki błąd "request for member `Length' in `inputData', which is of non-class type `unsigned char[1]' "
                                      
            byte[] outputData = CryptographyHelper.ComputeMD5(inputData);
 
            Console.WriteLine(CryptographyHelper.ToHexString(outputData));
0
unsigned char inputData[] = {len};

Ten zapis będzie równoważny jednej zmiennej do której będziemy się starać przypisać wartość 10 * 1024 * 1024, jak wiemy char ma tylko 256 bitów, więc będzie to niemożliwe. Aby stworzyć tablię która będzie miała 10mb elementów, to musisz zadeklarować tak:

unsigned char inputData[ len ] = { 0 } // = { 0 } nie jest konieczne ale spowoduje wyzerowanie całej tablicy

nie masz w C++ takiej metody jak .Lenght, która zwraca wielkość tablicy, do tego służy w C++ operator sizeof().

EDIT:
Poza tym, reszta kodu z C# nie przejdzie w C++.

0

w C++ nie wszystko jest obiektem. unsigned char nie ma pola length. Musisz użyc http://www.cplusplus.com/reference/clibrary/cstring/strlen/
ewentualnie zrób sizeof(inputData)/sizeof(unsigned char)

0

Ale czy ty przypadkiem nie piszesz w C++/CLI? CryptographyHelper to klasa z .NET ...
W każdym razie zakładam C++.

Wrzucanie 10MB na stos to zły pomysł (poczytaj o "stos vs. sterta" jeśli nie wiesz o co chodzi). Możesz alokować pamięć dynamicznie operatorem new

char *inputData = new char[len];
inputFile.read(inputData, 0, len); // w przypadku tablic dynamicznych rozmiar musimy pamiętać sobie sami, użyj zmiennej "len"
/*...*/
delete[] tab; // po skończonej pracy z tablicą zwalniamy pamięć!

albo użyć klasy vector:

vector<char> inputData(len);
inputFile.read(&inputData.front(), 0, inputData.length()); // klasa "vector" przechowuje również jego rozmiar i możemy skorzystać z metody "length"
/*...*/
// po skończonej pracy pamięć zostanie zwolniona "sama", razem ze zmienną "inputData"

Funkcją strlen nie da się mierzyć ilości danych binarnych. No i w cale robić tego nie trzeba, rozmiar jest z góry określony.

Poza tym licząc hash wystarczy czytać kolejne bajty z pliku strumieniowo, nie trzeba wczytywać wszytstkiego do tablicy. To tak a propos tego, że w C++ nie ma CryptographyHelper.

0

Trochę utknąłem z tą sumą kontrolną.
Dopiero zaczynam programowanie w c++.

Znalazłem taki kod do sumy kontrolnej:

#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <openssl/md5.h>
using namespace std;

int main(int argc, char *argv[])
{
    unsigned char c[MD5_DIGEST_LENGTH];
    char *filename="tdUnKnOwNt.avi";
    int i;
    FILE *inFile = fopen (filename, "rb");
    MD5_CTX mdContext;
    int bytes;
    unsigned char data[1024];
    
    if (inFile == NULL) {
        printf ("%s can't be opened.\n", filename);
        return 0;
    }
    MD5_Init (&mdContext);
    while ((bytes = fread (data, 1, 1024, inFile)) != 0)
        MD5_Update (&mdContext, data, bytes);
    MD5_Final (c,&mdContext);
    for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", c[i]);
    printf (" %s\n", filename);
    fclose (inFile);
    
    system("PAUSE");
    return EXIT_SUCCESS;
} 

Działa dobrze, tylko teraz jakaś podpowiedź, co tu zmienić aby czytał tylko pierwsze 10MB pliku. Bo z przejścia z C# sobie nie poradziłem :/

0
tomekmvr napisał(a):

while ((bytes = fread (data, 1, 1024, inFile)) != 0)
MD5_Update (&mdContext, data, bytes);
W tej pętli czytane są z pliku porcje bajtów po 1024 i przekazywane do obliczeń. Wystarczy, że ograniczysz wykonanie tej pętli do max. 10240 obiegów.

http://www.cplusplus.com/reference/clibrary/cstdio/fread/

0

czyli tak?

while ((bytes = fread (data, 1, 1024, inFile)) < 10241)
MD5_Update (&mdContext, data, bytes);

0

Nie tak.

0

Zrobiłem tak, teraz mam nadzieje że dobrze

#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <openssl/md5.h>
using namespace std;
int i=0;
int main(int argc, char *argv[])
{
    unsigned char c[MD5_DIGEST_LENGTH];
    char *filename="tdUnKnOwNt.avi";
    int i;
    FILE *inFile = fopen (filename, "rb");
    MD5_CTX mdContext;
    int bytes;
    unsigned char data[1024];
    
    if (inFile == NULL) {
        printf ("%s can't be opened.\n", filename);
        return 0;
    }
    MD5_Init (&mdContext);
    
    while ((bytes = fread (data, 1, 1024, inFile)) != 0 && i<10242)
    {
        MD5_Update (&mdContext, data, bytes);
        i++;
    }
    MD5_Final (c,&mdContext);
    for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", c[i]);
    printf (" %s\n", filename);
    fclose (inFile);
    
    system("PAUSE");
    return EXIT_SUCCESS;
} 
0

Ograniczyłem pętle do 10 * 1024, ale dla każdego pliku otrzymuję tą samą sumę kontrolną. Kod źródłowy jak w poprzednim poście.

1 użytkowników online, w tym zalogowanych: 0, gości: 1