// ------------------------------------------------ --------------------------- #include <vcl.h> #include <stdio.h> #include <conio.h> // ------------------------------------------------ --------------------------- // taken from the help, determine the file size long filesize (FILE * stream) { long curpos, length; curpos = ftell (stream); fseek (stream, 0L, SEEK_END); length = ftell (stream); fseek (stream, curpos, SEEK_SET); return length; } // function that implements the work of GOST 28147-89 in the simple replacement mode void rpz (int rezh, char * opener, char * saver) { FILE * f_begin, * f_end; // streams for source and destination files // replacement table byte Tab_Z [8] [16] = { 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF }; // key unsigned long key [8] = { 0x0123, 0x4567 0x89AB, 0xCDEF, 0x0123, 0x4567 0x89AB, 0xCDEF }; char N [4]; // 32-bit drive unsigned long n1 = 0, n2 = 0, SUM232 = 0; // drives N1, N2, and adder // open files f_begin = fopen (opener, "rb"); f_end = fopen (saver, "wb"); // determine the number of blocks float blokoff; blokoff = 8 * filesize (f_begin); blokoff = blokoff / 64; int block = blokoff; if (blokoff-block> 0) block ++; int sh; if (filesize (f_begin)> = 4) sh = 4; else sh = filesize (f_begin); int sh1 = 0; int flag = 0; // start reading and converting blocks // there are checks for the completeness of the blocks to read only the required number of bits for (int i = 0; i <block; i ++) { // write to drive N1 for (int q = 0; q <4; q ++) * ((byte *) & N + q) = 0x00; if ((sh1 + sh) <filesize (f_begin)) { fread (N, sh, 1, f_begin); sh1 + = sh; } else { sh = filesize (f_begin) -sh1; fread (N, sh, 1, f_begin); flag = 1; } n1 = * ((unsigned long *) & N); // write to N2 drive for (int q = 0; q <4; q ++) * ((byte *) & N + q) = 0x00; if ((sh1 + sh) <filesize (f_begin)) { fread (N, sh, 1, f_begin); sh1 + = sh; } else { if (flag == 0) { sh = filesize (f_begin) -sh1; fread (N, sh, 1, f_begin); } } n2 = * ((unsigned long *) & N); // 32 simple replacement cycles // read the key in the required GOST order int c = 0; for (int k = 0; k <32; k ++) { if (rezh == 1) {if (k == 24) c = 7; } else {if (k == 8) c = 7; } // sum in the adder CM1 SUM232 = key [c] + n1; // replace by replacement table byte first_byte = 0, second_byte = 0, zam_symbol = 0; int n = 7; for (int q = 3; q> = 0; q--) { zam_symbol = * ((byte *) & SUM232 + q); first_byte = (zam_symbol & 0xF0) >> 4; second_byte = (zam_symbol & 0x0F); first_byte = Tab_Z [n] [first_byte]; n--; second_byte = Tab_Z [n] [second_byte]; n--; zam_symbol = (first_byte << 4) | second_byte; * ((byte *) & SUM232 + q) = zam_symbol; } SUM232 = (SUM232 << 11) | (SUM232 >> 21); // cyclic shift by 11 SUM232 = n2 ^ SUM232; // add in the adder CM2 if (k <31) { n2 = n1; n1 = SUM232; } if (rezh == 1) { if (k <24) { c ++; if (c> 7) c = 0; } else { c--; if (c <0) c = 7; } } else { if (k <8) { c ++; if (c> 7) c = 0; } else { c--; if (c <0) c = 7; } } } n2 = SUM232; // output result to file char sym_rez; for (int q = 0; q <= 3; q ++) { sym_rez = * ((byte *) & n1 + q); fprintf (f_end, "% c", sym_rez); } for (int q = 0; q <= 3; q ++) { sym_rez = * ((byte *) & n2 + q); fprintf (f_end, "% c", sym_rez); } } fclose (f_begin); fclose (f_end); } // ------------------------------------------------ --------------------------- int main () { // choose encryption or decryption int rezhim = 0; do { printf ("Select the mode of operation: \ nCrypting - 1 \ nCoding - 2 \ n"); scanf ("% d", & rezhim); } while ((rezhim! = 1) && (rezhim! = 2)); // repeat until 1 or // select the source and destination files (slash '\' in the path to write as '\\') char open_str [50], save_str [50]; printf ("\ nEnter the path to the source file \ n"); scanf ("% s", & open_str); printf ("\ nEnter the path to the file where you want to write the result \ n"); scanf ("% s", & save_str); rpz (rezhim, open_str, save_str); // run the RPP return 0; } // ------------------------------------------------ ---------------------------
Source: https://habr.com/ru/post/81032/
All Articles