Stránka 3 z 4

Re: Vigenerova šifra - C

Napsal: 18 zář 2017 18:37
od popcorn
Také ne a navíc mohu zadat max. 100 znaků najednou protože tam mám char, takže bych musel postupně a když to chci přeložit tak nevím kde je chyba, ale přeloží to nějakou blbost..
output.png
output.png (11.64 KiB) Zobrazeno 798 x

Re: Vigenerova šifra - C

Napsal: 19 zář 2017 18:45
od faraon
Konečně zbyla chvilka času a zkusil jsem to dešifrovat ručně pomocí šifrovacího disku:

Kód: Vybrat vše

ETVKC PBGUE DYTPG
PCHEL PPCHE LPPCH
PROGR AMENA SJENZ

Vyšlo to, to ROG a A na začátku ti tam sedí, ale zbytek je úplně mimo. Tak teď uděláme ještě pár testů.

Zkus zadat jako zprávu celou abecedu:

Kód: Vybrat vše

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Tu zašifruj třemi hesly: A, B, Z. Mělo by ti vyjít tohle:

Kód: Vybrat vše

A: ABCDEFGHIJKLMNOPQRSTUVWXYZ (posun 0)
B: BCDEFGHIJKLMNOPQRSTUVWXYZA (posun 1)
Z: ZABCDEFGHIJKLMNOPQRSTUVWXY (posun 25)

Re: Vigenerova šifra - C

Napsal: 20 zář 2017 16:51
od popcorn
Tak šifrování vypadá, že funguje.
out.png


Dodatečně přidáno po 6 hodinách 25 minutách 59 vteřinách:
Tak jsem přišel na chybu v dešifrování! :)
místo:

Kód: Vybrat vše

             
                       if (islower((unsigned char)zprava[i])) {
                       hodnota = (((zprava[i]) - 'z') - ((heslo[j]) - 'z'));
                       }
                       if (isupper((unsigned char)message[i])) {
                       hodnota = (((zprava[i]) - 'A') - ((heslo[j]) - 'A'));   
                       }


Jsem to upravil na

Kód: Vybrat vše

           
                       if (islower((unsigned char)zprava[i])) {
                       hodnota = (((zprava[i] - heslo[j]) + 26) % 26);   
                       }
                       if (isupper((unsigned char)message[i])) {
                       hodnota = (((zprava[i] - heslo[j]) + 26) % 26);   
                       }


Ale zajímalo by mě, proč tam musí být ta 26 když 26 je →..

Re: Vigenerova šifra - C

Napsal: 20 zář 2017 23:30
od popcorn

Kód: Vybrat vše

programenasjenzjsivpametipozdravenobudjmenotveprijdoperacnisystemtvujbudvuleprikazutvychnatiskarnejakozjsounaobrazovcedatanasevezdejsidejznamdnesaodpustnamnasevstupniivystupnichybyjakozimyodpoustimevinikumsvadnymilogickymiobvodyneuvednasvezklamaniazbavnasnapetovychrazunebottvujjestalgoritmusiaplikaceiresenizacykleneaznavekyvekuvreturnn

Re: Vigenerova šifra - C

Napsal: 21 zář 2017 00:23
od faraon
Výborně, máš 1- :P

Ještě zkus přijít na to proč se ti poslední písmeno vypisuje dvakrát, někde se tam provádí něco navíc!

Není náhodou 26 počet písmen v anglické abecedě? Když ti ten posun na nějakou stranu přeteče nebo podteče, potřebuješ se vrátit zpět do povoleného rozsahu. Udělat kruh.

Ty kontrolní výpisy vstupů už nepotřebuješ, takže se můžou odstranit. Stačí je zakomentovat, ať je nemusíš psát znova, kdybys je ještě potřeboval. A sleduj co to provede, někdy se stane že po takovém čištění program přestane fungovat, protože ta kontrola dělala něco na čem jeho správný běh závisel - i proto je lepší nemazat je rovnou :lol:

Re: Vigenerova šifra - C

Napsal: 22 zář 2017 14:22
od popcorn
Tak to vůbec netušim, co se mi tam provádí navíc a proč tam tedy to písmenko se zopakuje na konci, možná něco u printf()?

Kód: Vybrat vše

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

int main(int argc, char **argv) {
    char zprava[100];
    int vyber;
    int i, j;
    char heslo[33];
    int hodnota;
    char opakovat = 1;

    while (opakovat == 1) {
        printf("Zadejte operaci\n");
        printf("Sifrovat - 1 \n");
        printf("Desifrovat - 2\n");

        scanf("%d", &vyber);

        if (vyber == 1) {
            printf("Zadejte zprávu k zašifrování\n");
            while (getchar() != '\n');
            fgets(zprava, 100, stdin);
            //printf("TEXT: ***%s***\n",zprava);

            printf("Zadejte heslo\n");
            scanf("%s", &heslo);
           //printf("PASSWORD: ***%s***\n",heslo);

            for (i = 0, j = 0; i < strlen(zprava); i++, j++) {
                if (zprava[i] == ' ')
                    continue;

                if (j >= strlen(heslo)) { 
                    j = 0;
                }
                if (islower((unsigned char)zprava[i])) {
                  hodnota = (((zprava[i]) - 'a') + ((heslo[j]) - 'a'));
                }
                if (isupper((unsigned char)zprava[i])) {
                  hodnota = (((zprava[i]) - 'A') + ((heslo[j]) - 'a'));   
                }
                 printf("%c", 97 + (hodnota % 26));
            }
            printf("\nChcete opakovat? [1/0]\n");
            scanf("%d", &opakovat);
          }
           else
        if (vyber == 2) {
            printf("Zadejte zprávu k dešifrování\n");
            while (getchar() != '\n');
            fgets(zprava, 100, stdin);
            //printf("TEXT: ***%s***\n",zprava);

            printf("Zadejte heslo\n");
            scanf("%s", &heslo);
            //printf("HESLO: ***%s***\n",heslo);

            for (i = 0, j = 0; i < strlen(zprava); i++, j++) {
                if (zprava[i] == ' ')
                    continue;

                if (j >= strlen(heslo)) { 
                    j = 0;
                }
                if (islower((unsigned char)zprava[i])) {
                  hodnota = (((zprava[i] - heslo[j]) + 26) % 26);   
                }
                if (isupper((unsigned char)zprava[i])) {
                  hodnota = (((zprava[i] - heslo[j]) + 26) % 26);   
                }
                if (hodnota < 0) {
                    hodnota = hodnota * -1;
                }
                 printf("%c", 97 + (hodnota % 26));
            }
            printf("Chcete opakovat?? [1/0]\n");
            scanf("%d", &opakovat);
        }
    }
    return (EXIT_SUCCESS);
}

Re: Vigenerova šifra - C

Napsal: 22 zář 2017 21:41
od faraon
Tak printf() to není, ten pracuje úplně správně. Koukni se co je za problém, a dělá to šifrování i dešifrování:

Kód: Vybrat vše

Zadejte zprávu k zašifrování
abc
TEXT: ***abc
***
STRLEN: ***4***

Teď se zrovna hodí že tam ty kontrolní výpisy zůstaly zakomentované, použil jsem je a ještě rozšířil...
Zadal jsem 3 písmena a délka je 4, jak je tohle možné? :-o
Zkus zapátrat na první stránce tématu (nebo v manuálové stránce) ;)

Další problém je, že jsem heslo musel zadat velkými písmeny, protože s malými to rozšifrovalo úplně jinak - špatně. To je chyba, obě velikosti by měly dát stejný výsledek, protože v téhle šifře se nerozlišují.

Re: Vigenerova šifra - C

Napsal: 23 zář 2017 09:50
od popcorn
Tak

Kód: Vybrat vše

fgets()
musí načítat i tu mezeru na konci, ale myslel jsem, že to jsme pořešili zde

Kód: Vybrat vše

while (getchar() != '\n');

Re: Vigenerova šifra - C

Napsal: 23 zář 2017 10:30
od faraon
Mezeru ti odstraní/přeskočí tohle:

Kód: Vybrat vše

                if (zprava[i] == ' ')
                    continue;

Ale co se stane s ostatními nepísmennými znaky? Musíš na to jít trochu jinak.
Zkusil jsem kontrolní výpis po znacích:

Kód: Vybrat vše

Zadejte zprávu k zašifrování
qwe-rtz
Zadejte heslo
a
113     q       113     q
119     w       119     w
101     e       101     e
45      -       101     e
114     r       114     r
116     t       116     t
122     z       122     z
10      \n      122     z

Tohle není úplně to co bys udělal jako šifrant na papíře ;-)

Re: Vigenerova šifra - C

Napsal: 23 zář 2017 10:48
od popcorn
Tak bych mohl použít funkci

Kód: Vybrat vše

if isalpha()... else 
abych šifroval jen písmena to by šlo né?

Re: Vigenerova šifra - C

Napsal: 23 zář 2017 10:58
od faraon
To by šlo.

Re: Vigenerova šifra - C

Napsal: 23 zář 2017 19:19
od popcorn
Tak hledal jsem na internetu, ale žádný návod jak pořádně použít tuto funkci jsem nenašel a já nikdy s touto funkcí nepracoval, tak nevim jak na to.