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.
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.
Zamiast byte
możesz użyc char
i zrobić z tego tablicę.
Powiadasz nie ma? A co powiesz na to http://www.example-code.com/vcpp/bytearray.asp ? :P
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));
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++.
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)
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
.
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 :/
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.
czyli tak?
while ((bytes = fread (data, 1, 1024, inFile)) < 10241)
MD5_Update (&mdContext, data, bytes);
Nie tak.
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;
}
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.