Witam
Tematem moich ostatnich prac było napisanie kodu dla szyfru afinicznego, poniżej kody:
* szyfr afiniczny modulo n, alfabet lacinski,
* tylko duze litery argumenty wywolania:
* ./afiniczne -e|-d a b
* gdzie
* -e : szyfrowanie
* -d : deszyfrowanie
* a b : klucz tajny
*/
#include <stdio.h>
#include <stdlib.h>
char alpha[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"~!@#$%^&*()_+"
"`1234567890-="
"<>?:\"{}|"
",./;'[]\\ "
"ˇĆĘŁŃÓ¦¬Ż"
"±ćęłń󶼿"
;
unsigned n= sizeof alpha / sizeof alpha[0] - 1;
unsigned nwd(unsigned, unsigned, int *, int *);
int ind( char, char* );
main(int argc, char *argv[])
{
int a, b, c, x, y;
unsigned d, i;
if (argc != 1 + 3) {
fprintf(stderr, "%s -e|-d a b\n\n", argv[0]);
return 1;
}
a = atoi(argv[2]);
if (a < 0)
a = n - (-a) % n;
else
a %= n;
b = atoi(argv[3]);
if (b < 0)
b = n - (-b) % n;
else
b %= n;
if (argv[1][0] != '-') {
fprintf(stderr, "%s -e|-d a b\n\n", argv[0]);
return 1;
}
if (argv[1][1] != 'e' && argv[1][1] != 'd') {
fprintf(stderr, "%s -e|-d a b\n\n", argv[0]);
return 1;
}
d = nwd(a, n, &x, &y);
if (d != 1) {
fprintf(stderr, "BLAD: a=%u w kluczu (%u, %u) jest "
"NIEODWRACALNE modulo %u.\n\n", a, a, b, n );
return 2;
}
if (argv[1][1] == 'd') {
int a0 = a, b0 = b;
a = x > 0 ? x % n : (n - (-x) % n);
b *= -a;
b = b >= 0 ? b % n : (n - (-b) % n);
fprintf(stderr,
"przeksztalcenie kluczy (%u, %u) => (%u, %u) mod %u\n"
"deszyfrowanie kluczem tajnym-odwrotnym: "
"(%u, %u) mod %u:\n",
a0, b0, a, b, n,
a, b, n );
} else
fprintf(stderr, "szyfrowanie kluczem tajnym: "
"(%u, %u) mod %u:\n", a, b, n);
while ((c = getchar()) != EOF)
if ( (i=ind(c, alpha))>=0 && i<n )
putchar( alpha[(a*i+b)%n] );
else
putchar(c);
return 0;
}
unsigned
nwd(unsigned a, unsigned b, int *x, int *y)
{
if (b == 0) {
*x = 1;
*y = 0;
return a;
} else {
unsigned d;
int x1, y1;
d = nwd(b, a % b, &x1, &y1);
*x = y1;
*y = x1 - y1 * (a / b);
return d;
}
}
int ind( char c, char *s ) {
char *q;
for( q=s; *q && *q!=c; ++q )
;
return *q?(q-s):(-1);
}
oraz
/*
* szyfr afiniczny modulo 26, alfabet lacinski,
* tylko duze litery argumenty wywolania:
* ./afiniczne -e|-d a b
* gdzie
* -e : szyfrowanie
* -d : deszyfrowanie
* a b : klucz tajny
*/
#include <stdio.h>
#include <stdlib.h>
unsigned nwd(unsigned, unsigned, int *, int *);
main(int argc, char *argv[])
{
int a, b, c, x, y;
unsigned d;
if (argc != 1 + 3) {
fprintf(stderr, "%s -e|-d a b\n\n", argv[0]);
return 1;
}
a = atoi(argv[2]);
if (a < 0)
a = 26 - (-a) % 26;
else
a %= 26;
b = atoi(argv[3]);
if (b < 0)
b = 26 - (-b) % 26;
else
b %= 26;
if (argv[1][0] != '-') {
fprintf(stderr, "%s -e|-d a b\n\n", argv[0]);
return 1;
}
if (argv[1][1] != 'e' && argv[1][1] != 'd') {
fprintf(stderr, "%s -e|-d a b\n\n", argv[0]);
return 1;
}
d = nwd(a, 26, &x, &y);
if (d != 1) {
fprintf(stderr, "BLAD: a=%u w kluczu (%u, %u) jest "
"NIEODWRACALNE modulo 26.\n\n", a, a, b);
return 2;
}
if (argv[1][1] == 'd') {
int a0 = a, b0 = b;
a = x > 0 ? x % 26 : (26 - (-x) % 26);
b *= -a;
b = b >= 0 ? b % 26 : (26 - (-b) % 26);
fprintf(stderr,
"przeksztalcenie kluczy (%u, %u) => (%u, %u) mod 26\n"
"deszyfrowanie kluczem tajnym-odwrotnym: "
"(%u, %u) mod 26:\n",
a0, b0, a, b,
a, b);
} else
fprintf(stderr, "szyfrowanie kluczem tajnym: "
"(%u, %u) mod 26:\n", a, b);
while ((c = getchar()) != EOF)
if ('A' <= c && c <= 'Z')
putchar('A' + (a * (c - 'A') + b) % 26);
else
putchar(c);
return 0;
}
unsigned
nwd(unsigned a, unsigned b, int *x, int *y)
{
if (b == 0) {
*x = 1;
*y = 0;
return a;
} else {
unsigned d;
int x1, y1;
d = nwd(b, a % b, &x1, &y1);
*x = y1;
*y = x1 - y1 * (a / b);
return d;
}
}
Chciałbym teraz napisać szyfr afiniczny z 256-elementowym alfabetem.
Ilość elementów w alfabecie (zakres bajtu: 0-255) daje mi możliwość wykorzystania programu do szyfrowania plików binarnych.
Siedzę nad tym dłuższy czas ale nie wiem co z tym począć.
Będę wdzięczny za pomoc.