C-language compressed files and examples of verifying file integrity with MD5 algorithm tutorial _c language

Source: Internet
Author: User
Tags md5 hash sprintf

Simple decompression of 7z files using the Lzma SDK
sometimes we only need to extract the LZMA algorithm compressed 7z files, sometimes need to extract on the embedded devices, using P7zip although supporting a variety of formats, but not easy to crop, using the LZMA SDK is preferred:
You can find various versions here: http://zh.sourceforge.jp/projects/sfnet_sevenzip/releases/
I downloaded the 4.65 version, the file name encoding support is not 9.20 good, Chinese may have a problem, but my needs do not need to support the Chinese filename, so enough to use.
After decompression first look at 7z this project, this example only file decompression operation, imitate can write a more concise decompression function:
The files you need can refer to the example:

Modify the 7ZMAIN.C.
Our goal is to write a function extract7z, receive parameters are 7z file path, output file path, you can perform all decompression.
Main calling Function:

Sres Szarex_open (Cszarex *p, Ilookinstream *instream, Iszalloc *allocmain, Iszalloc *alloctemp); 
 
Sres szar_extract ( 
  const Cszarex *p, Ilookinstream *instream, UInt32 fileindex, UInt32 *blockindex 
  , 
  Byte **outbuffer, 
  size_t *outbuffersize, 
  size_t *offset, 
  size_t *outsizeprocessed, 
  iszalloc *allocmain, 
  iszalloc *alloctemp); 

We first compile under windows:
The complete code is as follows:

/* 7zmain.c-test application for 7z Decoder/#include <stdlib.h> #include <stdio.h> #include <st 
 
ring.h> #define LOGD printf #define LOGE printf #include "7zCrc.h" #include "7zFile.h" #include "7zVersion.h" #include "7zAlloc.h" #include "7zExtract.h" #include "7zIn.h" int my_cdecl extract7z (const char* srcfile, const CH 
  ar* dstpath) {Cfileinstream archivestream; 
  Clooktoread Lookstream; 
  Cszarex DB; 
  Sres Res; 
  Iszalloc Allocimp; 
  Iszalloc Alloctempimp; 
 
  Char outpath[1024] = {0}; 
 
  LOGD ("7z ansi-c Decoder" my_version_copyright_date "\ n"); 
    if (Infile_open (&archivestream.file, srcfile)) {//open 7z file LOGE ("Can not Open input file\n"); 
  return 1; 
  } fileinstream_createvtable (&archivestream); 
 
  Looktoread_createvtable (&lookstream, False); 
  Lookstream.realstream = &archiveStream.s; 
 
  Looktoread_init (&lookstream); 
  Allocimp.alloc = Szalloc; 
 
  Allocimp.free = Szfree; ALloctempimp.alloc = szalloctemp; 
 
  Alloctempimp.free = szfreetemp; 
 
  Crcgeneratetable (); 
  Szarex_init (&AMP;DB); 
 
  res = Szarex_open (&db, &AMP;LOOKSTREAM.S, &allocimp, &alloctempimp); 
 
    if (res = = SZ_OK) {Int32 i; UInt32 blockindex = 0xFFFFFFFF; /* It can have any value before-I (if Outbuffer = 0) */Byte *outbuffer = 0; /* It must be 0 before the ' a ' for each new archive. * * size_t outbuffersize = 0; /* It can have any value before the (if Outbuffer = 0) * * LOGD ("Total file/directory count[%d]\n", Db.db.Num 
    Files); 
      for (i = db.db.numfiles-1 i >= 0; i--) {size_t offset; 
      size_t outsizeprocessed; 
 
      Cszfileitem *f = db.db.Files + i; 
      strcpy (Outpath, Dstpath); 
      strcat (Outpath, "/"); 
 
      strcat (Outpath, f->name); 
        if (f->isdir) {//dir logd ("dir [%s]\n", Outpath); 
        mkdir (Outpath); 
      Continue }else{//file logd ("file [%s]\n ", Outpath); res = Szar_extract (&db, &AMP;LOOKSTREAM.S, I, &blockindex, &outbuffer, &outbuffersize, &o 
        Ffset, &outsizeprocessed, &allocimp, &alloctempimp); 
        if (res!= SZ_OK) {break; 
          }else{cszfile outfile; 
          size_t Processedsize; 
            if (Outfile_open (&outfile, Outpath)) {LOGE ("can not Open output file\n"); 
            res = Sz_error_fail; 
          Break 
          } processedsize = outsizeprocessed; if (File_write (&outfile, Outbuffer + offset, &processedsize)!= 0 | | processedsize!= outsizeproces 
            SED) {LOGE ("can not write output file\n"); 
            res = Sz_error_fail; 
          Break 
            } if (File_close (&outfile)) {LOGE ("can not close output file\n"); 
            res = Sz_error_fail; 
          Break 
      } 
        }} ialloc_free (&allocimp, Outbuffer); 
 
  } szarex_free (&db, &allocimp); 
  File_close (&archivestream.file); 
    if (res = = SZ_OK) {logd ("Everything is ok\n"); 
  return 0; 
  } if (res = = sz_error_unsupported) LOGE ("decoder doesn ' t support this archive\n"); 
  else if (res = = Sz_error_mem) LOGE ("Can not allocate memory\n"); 
  else if (res = = SZ_ERROR_CRC) LOGE ("CRC error\n"); 
  else LOGE ("ERROR #%d\n", res); 
return 1; 
int main (int numargs, char *args[]) {return extract7z (args[1], args[2]); 
 }


I'm using eclipse to compile with MinGW.

Execution effect, can decompress correctly.
Such decompression can only be used for simple decompression, does not support encryption, parameter 2 of the output file path of all folders must exist, compressed folder does not need to exist, uncompressed will be automatically created.
The folder in the compressed package cannot be Chinese, otherwise garbled.


Verifying file integrity or password correctness using the MD5 algorithm
MD5 is the message-digest algorithm 5 (Information-Digest algorithm 5), which is used to ensure complete consistency of information transmission. is one of the most widely used hashing algorithms (also translated digest algorithm, hashing algorithm), the mainstream programming language has been MD5 realized.
The basic principle of hashing algorithm is to calculate data (such as Chinese characters) as another fixed length value, and the predecessor of MD5 is MD2, MD3 and MD4.
The role of MD5 is to allow bulk information to be "compressed" into a confidential format (that is, to transform an arbitrary length of a byte string into a certain length of hexadecimal numbers) before signing the private key with the digital signature software.
MD5 in practical applications usually have two uses, one is to calculate the MD5 value of a string, often used for password-related operations, the other is used to calculate the MD5 value of a file, generally used in network transport to verify the file error.
The following is the C language of the MD5 Computing program, from StarDict, the popular code on the Internet are similar:

Md5.h

#ifndef md5_h #define MD5_H #ifdef __cplusplus extern "C" {#endif/* __cplusplus * * #ifdef HAVE_CO 
Nfig_h # include "Config.h" #endif #ifdef have_stdint_h #include <stdint.h> typedef uint32_t UINT32; 
#else/* A.leo.: this wont work on bits platforms;) * * typedef unsigned UINT32; 
  #endif #define Md5_file_buffer_len 1024 struct Md5context {uint32 buf[4]; 
  UInt32 bits[2]; 
unsigned char in[64]; 
 
}; 
void Md5init (struct md5context *context); 
void Md5update (struct md5context *context, unsigned char const *BUF, unsigned len); 
void md5final (unsigned char digest[16], struct md5context *context); 
 
void Md5transform (UInt32 buf[4], UInt32 const IN[16]); 
int getBytesMD5 (const unsigned char* src, unsigned int length, char* MD5); 
int getStringMD5 (const char* SRC, char* MD5); 
 
int getFileMD5 (const char* path, char* MD5); 
 * * is needed to make rsaref happy on some MS-DOS compilers. * * typedef struct MD5CONTEXT Md5_ctx; #ifdef __cplusplus} #endif/* __cplusplus */#endif/*! 

 Md5_h *

Source file:
md5.c

#include <string.h>/* for memcpy () */#include <stdio.h> #include "md5.h" #ifndef highfirst #define 
 
Bytereverse (buf, len)/* Nothing/#else void Bytereverse (unsigned char *buf, unsigned longs); 
 #ifndef ASM_MD5/* note:this code is harmless on Little-endian machines. 
  */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 #endif static void Putu32 (UInt32 data, unsigned char *addr) {addr[0] = (unsigned char) data; 
  ADDR[1] = (unsigned char) (data >> 8); 
  ADDR[2] = (unsigned char) (data >> 16); 
ADDR[3] = (unsigned char) (data >> 24); } * * Start MD5 accumulation. 
 Set bit count to 0 and buffer to mysterious * initialization constants. */void Md5init (struct md5context *ctx) {ctx->buf[0] = 0x67452301; 
  CTX-&GT;BUF[1] = 0xefcdab89; 
  CTX-&GT;BUF[2] = 0x98badcfe; 
 
  CTX-&GT;BUF[3] = 0x10325476; 
  Ctx->bits[0] = 0; 
Ctx->bits[1] = 0; 
 } * * Update context to reflect the concatenation of another buffer full * of bytes. 
 
  */void Md5update (struct md5context *ctx, unsigned char const *BUF, unsigned len) {UInt32 T; 
  /* Update Bitcount */t = ctx->bits[0]; if ((ctx->bits[0] = t + ((uint32) Len << 3)) < T) ctx->bits[1]++; 
 
  /* Carry from low to High */ctx->bits[1] + = len >> 29; t = (t >> 3) & 0x3f;  /* Bytes already in Shsinfo->data/* Handle any leading odd-sized chunks */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; 
 } /* Process data in 64-byte chunks */while (len >=) {memcpy (ctx->in, buf, 64); 
    Bytereverse (Ctx->in, 16); 
    Md5transform (Ctx->buf, (UInt32 *) ctx->in); 
    BUF + 64; 
  Len-= 64; }/* Handle any remaining bytes of data. 
* * memcpy (ctx->in, buf, Len); } * * Final Wrapup-pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, msb-firs 
  T) */void md5final (unsigned char digest[16], struct md5context *ctx) {unsigned count; 
 
  unsigned char *p; 
 
  /* Compute number of bytes MoD/count = (Ctx->bits[0] >> 3) & 0x3F; /* Set the padding to 0x80. 
  This is safe since there are always at least one byte/p = ctx->in + count; 
 
  *p++ = 0x80; 
 
  /* Bytes of padding needed to make Bytes * * count = 64-1-count; /* Pad out to the MoD/if (count < 8) {/* Two lots of padding:pad the ' IMset (p, 0, Count); 
    Bytereverse (Ctx->in, 16); 
 
    Md5transform (Ctx->buf, (UInt32 *) ctx->in); 
  /* Now fill the next blocks with bytes * * memset (ctx->in, 0, 56); 
  else {/* Pad blocks to bytes * * memset (p, 0, count-8); 
 
  } bytereverse (Ctx->in, 14); 
  /* Append length in bits and transform *///((UInt32 *) ctx->in) [+] = ctx->bits[0]; 
  ((UInt32 *) ctx->in) = ctx->bits[1]; 
  Putu32 (Ctx->bits[0], ctx->in + 56); 
 
  Putu32 (Ctx->bits[1], ctx->in + 60); 
  Md5transform (Ctx->buf, (UInt32 *) ctx->in); 
  Bytereverse ((unsigned char *) CTX-&GT;BUF, 4); 
  memcpy (Digest, Ctx->buf, 16); memset (CTX, 0, sizeof (*CTX)); /* In case it ' s sensitive/} #ifndef ASM_MD5/* The four core functions-f1 is optimized somewhat/* #defi 
Ne F1 (x, Y, Z) (X & y | ~x & z) */#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) #defineF4 (x, Y, z) (y ^ (x | ~z))/* This is the MD5 algorithm. * * #define MD5STEP (F, W, X, Y, Z, data, s) \ (w + f (x, Y, z) + data, W = W<<s | w>> (32-s), w = = x)/ * The core of the MD5 algorithm, this alters a existing MD5 hash to * reflect the addition of longwords of new D Ata. 
 Md5update blocks * The data and converts bytes into longwords for this routine. 
 
  * * void Md5transform (UInt32 buf[4], UInt32 const 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; } * * Get MD5 of A byTE buffer */int getBytesMD5 (const unsigned char* src, unsigned int length, char* md5) {unsigned char i = 0; 
  unsigned char md5bytes[16] = {0}; 
  Md5_ctx context; 
  if (src = null | | md5 = NULL) {return-1; 
  } md5init (&context); 
  Md5update (&context, src, length); 
  Md5final (Md5bytes, &context); 
    for (i = 0; i < i++) {sprintf (MD5, "%02x", Md5bytes[i]); 
  MD5 + 2; 
  } *md5 = ' I '; 
return 0; }/* Get MD5 for a string */int getStringMD5 (const char* SRC, char* MD5) {return getBytesMD5 (unsigned char 
*) SRC, strlen ((char*) src), MD5); 
  /** * Get MD5 of a file */int getFileMD5 (const char* path, char* MD5) {file* fp = NULL; 
  unsigned char Buffer[md5_file_buffer_len] = {0}; 
  int count = 0; 
  Md5_ctx context; 
  unsigned char md5bytes[16] = {0}; 
  int i; 
  if (path = = NULL | | md5 = NULL) {return-1; 
  fp = fopen (path, "RB"); 
  if (fp = = NULL) {return-1; } md5iNIT (&context); 
  while (count = fread (buffer, 1, Md5_file_buffer_len, FP)) > 0) {md5update (&context, buffer, count); 
  } md5final (Md5bytes, &context); 
    for (i = 0; i < i++) {sprintf (MD5, "%02x", Md5bytes[i]); 
  MD5 + 2; 
  } *md5 = ' I '; 
return 0; 

 } #endif

The following is the code that calls the function calculation MD5:
Main.c

#include <stdio.h> 
#include <string.h> 
 
#include "md5.h" 
 
int main (int c, char** v) { 
  Char BUFFER[128]; 
  GetStringMD5 ("Hello World", buffer); 
  printf ("%s\n", buffer); 
  GetFileMD5 ("Hello.pdf", buffer); 
  printf ("%s\n", buffer); 
  return 0; 

Calculated correctly:


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.