Vigenerova šifra - C

Místo pro dotazy a rady ohledně programovacích jazyků (C++, C#, PHP, ASP, Javascript, VBS..) a tvorby webových stránek

Moderátor: Mods_senior

popcorn
Level 3
Level 3
Příspěvky: 525
Registrován: 07 črc 2016 21:02

Re: Vigenerova šifra - C

Příspěvek 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 1029 x
CPU: i5-6500 GPU: Msi RX480 8GB RAM: Crucial 2x8GB MB: MSI B150 PSU: Seasonic S12II-520 CASE: Gladius M35
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7408
Registrován: 23 pro 2010 09:23

Re: Vigenerova šifra - C

Příspěvek 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)
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
popcorn
Level 3
Level 3
Příspěvky: 525
Registrován: 07 črc 2016 21:02

Re: Vigenerova šifra - C

Příspěvek 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 →..
CPU: i5-6500 GPU: Msi RX480 8GB RAM: Crucial 2x8GB MB: MSI B150 PSU: Seasonic S12II-520 CASE: Gladius M35
popcorn
Level 3
Level 3
Příspěvky: 525
Registrován: 07 črc 2016 21:02

Re: Vigenerova šifra - C

Příspěvek od popcorn »

Kód: Vybrat vše

programenasjenzjsivpametipozdravenobudjmenotveprijdoperacnisystemtvujbudvuleprikazutvychnatiskarnejakozjsounaobrazovcedatanasevezdejsidejznamdnesaodpustnamnasevstupniivystupnichybyjakozimyodpoustimevinikumsvadnymilogickymiobvodyneuvednasvezklamaniazbavnasnapetovychrazunebottvujjestalgoritmusiaplikaceiresenizacykleneaznavekyvekuvreturnn 
CPU: i5-6500 GPU: Msi RX480 8GB RAM: Crucial 2x8GB MB: MSI B150 PSU: Seasonic S12II-520 CASE: Gladius M35
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7408
Registrován: 23 pro 2010 09:23

Re: Vigenerova šifra - C

Příspěvek 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:
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
popcorn
Level 3
Level 3
Příspěvky: 525
Registrován: 07 črc 2016 21:02

Re: Vigenerova šifra - C

Příspěvek 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);
}
CPU: i5-6500 GPU: Msi RX480 8GB RAM: Crucial 2x8GB MB: MSI B150 PSU: Seasonic S12II-520 CASE: Gladius M35
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7408
Registrován: 23 pro 2010 09:23

Re: Vigenerova šifra - C

Příspěvek 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í.
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
popcorn
Level 3
Level 3
Příspěvky: 525
Registrován: 07 črc 2016 21:02

Re: Vigenerova šifra - C

Příspěvek 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');
CPU: i5-6500 GPU: Msi RX480 8GB RAM: Crucial 2x8GB MB: MSI B150 PSU: Seasonic S12II-520 CASE: Gladius M35
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7408
Registrován: 23 pro 2010 09:23

Re: Vigenerova šifra - C

Příspěvek 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 ;-)
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
popcorn
Level 3
Level 3
Příspěvky: 525
Registrován: 07 črc 2016 21:02

Re: Vigenerova šifra - C

Příspěvek 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é?
CPU: i5-6500 GPU: Msi RX480 8GB RAM: Crucial 2x8GB MB: MSI B150 PSU: Seasonic S12II-520 CASE: Gladius M35
Uživatelský avatar
faraon
Master Level 8.5
Master Level 8.5
Příspěvky: 7408
Registrován: 23 pro 2010 09:23

Re: Vigenerova šifra - C

Příspěvek od faraon »

To by šlo.
"Král Lávra má dlouhé oslí uši, král je ušatec!

(pravil K. H. Borovský o cenzuře internetu)
popcorn
Level 3
Level 3
Příspěvky: 525
Registrován: 07 črc 2016 21:02

Re: Vigenerova šifra - C

Příspěvek 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.
CPU: i5-6500 GPU: Msi RX480 8GB RAM: Crucial 2x8GB MB: MSI B150 PSU: Seasonic S12II-520 CASE: Gladius M35
Odpovědět

Zpět na „Programování a tvorba webu“