Не глянешь на код? Может найдешь ошибки. А то я запутался совсем...
//---------------------------------------------------------------------------
#include <stdio.h>
#include <conio.h>
//---------------------------------------------------------------------------
// взято из хелпа, определяем размер файла
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;
}
// функция, реализующая работу ГОСТ 28147-89 в режиме простой замены
void rpz(int rezh, char* opener, char* saver)
{
FILE *f_begin, *f_end; // потоки для исходного и конечного файлов
// таблица замен
unsigned char 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,
};
// ключик
unsigned long key[8] =
{
0x0123,
0x4567,
0x89AB,
0xCDEF,
0x0123,
0x4567,
0x89AB,
0xCDEF,
};
char N[4]; // 32-разрядный накопитель,
unsigned long n1=0, n2=0, SUM232=0; // накопители N1, N2, и сумматор
// открываем файлы
f_begin = fopen (opener,"rb");
f_end = fopen (saver,"wb");
// определим количество блоков
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;
// начнем считывание и преобразование блоков
// присутствуют проверки на полноту блоков, чтобы считать только нужное количество бит
for (int i=0; i<block; i++)
{
// записываем в накопитель N1
for (int q1=0; q1<4; q1++) *((unsigned char *)&N+q1) = 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);
// записываем в накопитель N2
for (int q2=0; q2<4; q2++) *((unsigned char *)&N+q2) = 0x00;
// memset(N,0,sizeof(N));
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 цикла простой замены
// ключ считываем в требуемом ГОСТом порядке
int c = 0;
for (int k=0; k<32; k++)
{
if (rezh==1) { if (k==24) c = 7; }
else { if (k==8) c = 7; }
// суммируем в сумматоре СМ1
SUM232 = key[c] + n1;
// заменяем по таблице замен
unsigned char first_byte=0,second_byte=0,zam_symbol=0;
int n = 7;
for (int a=3; a>=0; a--)
{
zam_symbol = *((unsigned char *)&SUM232+a);
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;
*((unsigned char *)&SUM232+a) = zam_symbol;
}
SUM232 = (SUM232<<11)|(SUM232>>21); // циклический сдвиг на 11
SUM232 = n2^SUM232; // складываем в сумматоре СМ2
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;
// вывод результата в файл
char sym_rez;
for (int q3=0; q3<=3; q3++)
{
sym_rez = *((unsigned char *)&n1+q3);
fprintf(f_end, "%c", sym_rez);
}
for (int q4=0; q4<=3; q4++)
{
sym_rez = *((unsigned char *)&n2+q4);
fprintf(f_end, "%c", sym_rez);
}
}
fclose (f_begin);
fclose (f_end);
}
//---------------------------------------------------------------------------
int main()
{
// выбираем шифрование или расшифрование
int rezhim = 0;
do
{
printf("Vuberite rejum rabotu:\nShufrovanie - 1\nRasshufrovanie - 2\n");
scanf("%d", &rezhim);
} while ((rezhim!=1)&&(rezhim!=2)); // повторяем до тех пор, пока не будет введено 1 или
// выбираем исходный и конечный файлы (слэш '\' в пути писать как '\\')
char open_str[50], save_str[50];
printf("\nVvedite adres faila\n");
scanf("%s", &open_str);
printf("\nVvedite imja zashufrovanogo faila\n");
scanf("%s", &save_str);
rpz(rezhim, open_str, save_str); // запускаем РПЗ
return 0;
}
//------------------------------------------------------------------------