Ĺadny brzuch
Proszę o wskazówki w implementacji szyfru okresowo permutacyjnego
w języku najlepiej ANSI C, ostatecznie w C++.
Trochę teorii:
Szyfry okresowe permutacyjne
- permutacja ze stałym okresem d,
- znaki tekstu jawnego są przestawiane ze stałym okresem d
Przykład:
Słowo:
KRYPTOGRAFIA
d = 4
f(i) = 3 4 1 2
i = 1 2 3 4
- pierwsza litera tekstu jawnego przechodzi na pozycję 3,
druga na pozycję 4, trzecia na 1, czwarta na 2
- tekst jawny dzielimy na grupy d znakowe
- dla każdej grupy wykonujemy permutację zgodnie z funkcją f
(wyznaczamy pozycję dla znaków zgodnie z funkcją f)
--
K 1 -> 3
R 2 -> 4
Y 3 -> 1
P 4 -> 2
3 4 1 2
Y P K R
--
T 1 -> 3
O 2 -> 4
G 3 -> 1
R 4 -> 2
3 4 1 2
G R T O
--
A 1 -> 3
F 2 -> 4
I 3 -> 1
A 4 -> 2
I A A F
3 4 1 2
--
Zaszyfrowane:
YPKRGRTOIAAF
Mam teraz taką wizję w realizacji szyfru(w zasadzie niewiele).
Kod zamieściłem na:
http://phpfi.com/221351
Sama wizja dzielenia po np. 4 znaki, może realizować taka pętla?
for(int i = 0; i < ilosc_czarow; i++) { if( (( i + 1) % 4) == 0) { int tablica[100]; tablica[i] = i; } }
Do teorii fgets doszedłem, choć pobierania zamieściłem
w petli while linia 30 kodu.
Co do tej permutacji wg np. 3 4 1 2, to zrozumiałem,
że, trzeba działac funkcja na indeks,
np. wejscie[i+1], czyli dobrać tak, aby bylo 3 4 1 2.
Zastrzeżenie co do stalej tablicy, to można sobie darować,
choć słyszałem, ze realizacji powinna byc taka
char pikwe[]; char znak = getc(we); plikwe[i] = new char;
proszę zrozumieć, ze staram sie nadrabiać zaległości
w języku w miarę swoich możliwości.
Nie chce mi sie pisac w c bo za dlugo bym sie bawil. Pseudokod:
txt - text jawny out - tekst zaszyfrowany d - okres tab - tablica podstawnikow - kolejnosc przestawiania znakow for (i=0; i<ceil(length(txt)/4); ++i) { char s[d]; for (j=0; j<d; ++j) { s[tab[j]] = txt[i+j]; }; out = out+s; };
// Wyszedl pseudo c kod xD. Trzeba troche pozmieniac i bedzie nawet dzialc ;].
Kod (kod zamiany znakow, bo petla glowna owszem) nie przewiduje tego ze dlugosc tekstu wejsciowego nie jest podzielna przez d.
Użytkownik Ali240 edytował ten post 29 marzec 2007, 22:38
Dysponuje kodem, który wywala się przy np. alamakota i okres 4. Nie wiadome czemu.
#include <stdio.h> #include <string.h> #include <stdlib.h> const int okres = 4; const int tablicaPrzejsc[4] = {2, 3, 0, 1}; const char* nazwaPlikuWe = "dane.txt"; int main(void) { char* bufor = (char*) malloc(sizeof(char) * okres + 1); FILE* plikWy = stdout; FILE* plikWe; plikWe = fopen(nazwaPlikuWe, "r"); // wczytaj porcje znakow i je przetworz while (fgets(bufor, okres+1, plikWe)) { // wypisz znaki w odpowiedniej kolejnosci if(bufor[0] != '\n') for (int i = 0; i < okres; i++) fputc(bufor[tablicaPrzejsc[i]], plikWy); } fclose(plikWe); free(bufor); return 0; }
Nadal nie napisałeś (albo nie doczytałem) co się ma dziać jeśli długość tekstu jest niepodzielna przez d. Pomijając taka możliwość, oto moje rozwiązanie (zamiast plików użyłem standardowego wyjścia/wejścia):
#include <stdio.h> #define max 1000 char s[max+1]; char res[max+1]; int main() { int d; scanf("%s\n",&s); scanf("%d",&d); int szyfr[d]; int i; for (i=0;i<d;i++) scanf("%d",&szyfr[i]); int j=0; while (j+d<max) { for (i=0;i<d;i++) { res[i+j] = s[szyfr[i]-1+j]; } j+=d; } printf("%s",res); return 0; }
edit: jeszcze może format wejścia :P
3 linijki:
1. linijka - słowo do zaszyfrowania
2. linijka - d (okres)
3. linijka - d liczb całkowitych stanowiących opis funkcji f
np. kryptografia 4 3 4 1 2
Użytkownik bryn edytował ten post 25 kwiecień 2007, 19:55
W Twoim kodzie mamy tak:
wprowadzam:
alamakota 4 3 4 1 2
wynik:
amalotak
brakuje przepisania znaku co nie podlega
szyfrowaniu.
a
Użytkownik TAXIarz edytował ten post 26 kwiecień 2007, 06:15
zanotowane.pl doc.pisz.pl pdf.pisz.pl zsf.htw.pl
w języku najlepiej ANSI C, ostatecznie w C++.
Trochę teorii:
Szyfry okresowe permutacyjne
- permutacja ze stałym okresem d,
- znaki tekstu jawnego są przestawiane ze stałym okresem d
Przykład:
Słowo:
KRYPTOGRAFIA
d = 4
f(i) = 3 4 1 2
i = 1 2 3 4
- pierwsza litera tekstu jawnego przechodzi na pozycję 3,
druga na pozycję 4, trzecia na 1, czwarta na 2
- tekst jawny dzielimy na grupy d znakowe
- dla każdej grupy wykonujemy permutację zgodnie z funkcją f
(wyznaczamy pozycję dla znaków zgodnie z funkcją f)
--
K 1 -> 3
R 2 -> 4
Y 3 -> 1
P 4 -> 2
3 4 1 2
Y P K R
--
T 1 -> 3
O 2 -> 4
G 3 -> 1
R 4 -> 2
3 4 1 2
G R T O
--
A 1 -> 3
F 2 -> 4
I 3 -> 1
A 4 -> 2
I A A F
3 4 1 2
--
Zaszyfrowane:
YPKRGRTOIAAF
Mam teraz taką wizję w realizacji szyfru(w zasadzie niewiele).
Kod zamieściłem na:
http://phpfi.com/221351
Sama wizja dzielenia po np. 4 znaki, może realizować taka pętla?
for(int i = 0; i < ilosc_czarow; i++) { if( (( i + 1) % 4) == 0) { int tablica[100]; tablica[i] = i; } }
Do teorii fgets doszedłem, choć pobierania zamieściłem
w petli while linia 30 kodu.
Co do tej permutacji wg np. 3 4 1 2, to zrozumiałem,
że, trzeba działac funkcja na indeks,
np. wejscie[i+1], czyli dobrać tak, aby bylo 3 4 1 2.
Zastrzeżenie co do stalej tablicy, to można sobie darować,
choć słyszałem, ze realizacji powinna byc taka
char pikwe[]; char znak = getc(we); plikwe[i] = new char;
proszę zrozumieć, ze staram sie nadrabiać zaległości
w języku w miarę swoich możliwości.
Nie chce mi sie pisac w c bo za dlugo bym sie bawil. Pseudokod:
txt - text jawny out - tekst zaszyfrowany d - okres tab - tablica podstawnikow - kolejnosc przestawiania znakow for (i=0; i<ceil(length(txt)/4); ++i) { char s[d]; for (j=0; j<d; ++j) { s[tab[j]] = txt[i+j]; }; out = out+s; };
// Wyszedl pseudo c kod xD. Trzeba troche pozmieniac i bedzie nawet dzialc ;].
Kod (kod zamiany znakow, bo petla glowna owszem) nie przewiduje tego ze dlugosc tekstu wejsciowego nie jest podzielna przez d.
Użytkownik Ali240 edytował ten post 29 marzec 2007, 22:38
Dysponuje kodem, który wywala się przy np. alamakota i okres 4. Nie wiadome czemu.
#include <stdio.h> #include <string.h> #include <stdlib.h> const int okres = 4; const int tablicaPrzejsc[4] = {2, 3, 0, 1}; const char* nazwaPlikuWe = "dane.txt"; int main(void) { char* bufor = (char*) malloc(sizeof(char) * okres + 1); FILE* plikWy = stdout; FILE* plikWe; plikWe = fopen(nazwaPlikuWe, "r"); // wczytaj porcje znakow i je przetworz while (fgets(bufor, okres+1, plikWe)) { // wypisz znaki w odpowiedniej kolejnosci if(bufor[0] != '\n') for (int i = 0; i < okres; i++) fputc(bufor[tablicaPrzejsc[i]], plikWy); } fclose(plikWe); free(bufor); return 0; }
Nadal nie napisałeś (albo nie doczytałem) co się ma dziać jeśli długość tekstu jest niepodzielna przez d. Pomijając taka możliwość, oto moje rozwiązanie (zamiast plików użyłem standardowego wyjścia/wejścia):
#include <stdio.h> #define max 1000 char s[max+1]; char res[max+1]; int main() { int d; scanf("%s\n",&s); scanf("%d",&d); int szyfr[d]; int i; for (i=0;i<d;i++) scanf("%d",&szyfr[i]); int j=0; while (j+d<max) { for (i=0;i<d;i++) { res[i+j] = s[szyfr[i]-1+j]; } j+=d; } printf("%s",res); return 0; }
edit: jeszcze może format wejścia :P
3 linijki:
1. linijka - słowo do zaszyfrowania
2. linijka - d (okres)
3. linijka - d liczb całkowitych stanowiących opis funkcji f
np. kryptografia 4 3 4 1 2
Użytkownik bryn edytował ten post 25 kwiecień 2007, 19:55
W Twoim kodzie mamy tak:
wprowadzam:
alamakota 4 3 4 1 2
wynik:
amalotak
brakuje przepisania znaku co nie podlega
szyfrowaniu.
a
Użytkownik TAXIarz edytował ten post 26 kwiecień 2007, 06:15