Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: kryptaukseni ei liene toimivansa

Sivun loppuun

water flea [22.10.2005 12:51:38]

#

/*
jos tuntuu siltä, niin kertokaa onko vika algoritmissa vai
itse koodissa, kun ei kryptaa oikein tota tekstiä
kertokaa samalla onko okei laittaa putkaan omia koodeja
korjattaviksi
*/

#include <iostream>
#include <string>
#include <fstream>
#include <time.h>

using namespace std;

char* resize(char* data, int oldsize, int newsize, char filler='\n');
char* EC(char* data, int ndata, const char* key, int nkey, bool deletedata=false, int ikey=0);
char* DC(char* data, int ndata, const char* key, int nkey, bool deletedata=false, int ikey=-2);

int main()
{
	/*char* avain=new char[16];
	avain[0]=67;
	avain[1]=175;
	avain[2]=250;
	avain[3]=91;
	avain[4]=78;
	avain[5]=6;
	avain[6]=203;
	avain[7]=198;
	avain[8]=109;
	avain[9]=47;
	avain[10]=155;
	avain[11]=83;
	avain[12]=98;
	avain[13]=42;
	avain[14]=83;
	avain[15]=19;
	char* c="jukopliutamasokistit";
	char* ccrypted=EC(c,21,avain,16);
	char* cdecrypted=DC(ccrypted,21,avain,16);
	ccrypted=resize(ccrypted,21,22,'\0');
	avain=resize(avain,16,17,'\0');
	/*
	kerrotaan käyttäjälle mitä ohjelma on saanut aikaan
	*/
	/*cout << c << " kryptattuna avaimella " << avain << " on\n"
		<< ccrypted << " ja dekryptauksen tulos on " << cdecrypted <<"\n";
	delete [] ccrypted;
	delete [] cdecrypted;*/
	for (int i=0;i<10;i++)			// vertaillaan EC:n tuloksia eri avaimella ja
	{								// samalla kryptattavalla tekstillä
		char* avain=new char[5];	// tehdään avain
		avain[0]=i*25;				// asetetaan arvot
		avain[1]=50;
		avain[2]=100;
		avain[3]=150;
		avain[4]=200;
		char* c="cryptattava";
		cout << c << "->" << EC(c,11,avain,5) << "\n";
		//cout << c << "->" << DC(EC(c,12,avain,5),12,avain,6) << "\n";
	}
	return 0;
}

/* (resize)
turha selittää kun ei ole käytössä
deletoi data:n ja palauttaa taulukon, jolla on sama sisältö kuin data:lla,
mutta eri kokoisena ja siten, että ylimääräisiin alkioihin on pistetty
filler:in sisältö
*/
char* resize(char* data, int oldsize, int newsize, char filler)
{
	char * vali=new char[newsize];
	for (int i=0;i<oldsize&&i<newsize;i++)
	{
		vali[i]=data[i];
	}
	if (newsize>oldsize)
		for (int i=oldsize;i<newsize;i++)
			vali[i]=filler;
	delete [] data;
	return vali;
}

char* EC(char* data, int ndata, const char* key, int nkey, bool deletedata, int ikey)
{
	if (ikey>=nkey) return data;		// palautetaan data käsittelemättömänä kun rekursio päättyy
	char* encrypted=new char[ndata];	// luodaan ndata:n kokoinen taulukko, johon data kryptataan
	encrypted[0]=data[0]^key[ikey];		// xorrataan datan eka alkio key[ikey]:llä
										// ikey on se key:n alkio, jolla tällä kertaa xorrataan data
										// ikey:n arvoina käydään läpi rekursiossa kaikki key:n alkiot
	for (int i=1;i<ndata;i++)			// xorrataan loput alkiot ekan alkion perusteella
	{
		encrypted[i]=data[i-1]^data[i];
	}
	if (deletedata) delete [] data;		// data deletoidaan, jos funktiota on kutsuttu EC:n sisältä
										// muuttujaa tarvitaan, sillä kun käyttäjä kutsuu funktiota,
										// se ei saa tuhota data:a, mutta kun se kutsuu itseään
										// täytyy data tuhota, jottei ilmaan jäisi varattua taulukkoa
										// jokaista kutsuttua funktiota kohti
	return EC(encrypted,ndata,key,nkey,true,ikey+1);	// rekursio-plop
}

char* DC(char* data, int ndata, const char* key, int nkey, bool deletedata, int ikey)
{
	if (ikey==-2) ikey=nkey-1; // DC on EC:n palautus, joten sitä lie turha sen tarkemmin kommentoida
	if (ikey==-1) return data;
	char* decrypted=new char[ndata];
	decrypted[0]=data[0]^key[ikey];
	for (int i=1;i<ndata;i++)
	{
		decrypted[i]=decrypted[i-1]^data[i];
	}
	if (deletedata) delete [] data;
	return DC(decrypted,ndata,key,nkey,true,ikey-1);
}

/*char* EC(const char* data, int ndata, const char* key, int nkey)
{
	char* encrypted=new char[ndata];
	for (int ik=0;ik<nkey;ik++)
	{
		encrypted[0]=data[0]^key[ik];
		for (int i=1;i<ndata;i++)
		{
			encrypted[i]=data[i-1]^data[i];
		}
	}
	return encrypted;
}

char* DC(const char* data, int ndata, const char* key, int nkey)
{
	char* decrypted=new char[ndata];
	for (int ik=0;ik<nkey;ik++)
	{
		decrypted[0]=data[0]^key[ik];
		for (int i=1;i<ndata;i++)
		{
			decrypted[i]=decrypted[i-1]^data[i];
		}
	}
	return decrypted;
}*/

Mod Huom. Käytetääs niitä kooditageja

Metabolix [22.10.2005 13:50:52]

#

"... ei liene toimivansa." Opettele suomea :)

Mikäs ongelma tuossa on? Yleensä kannattaa kertoa mieluummin se kuin vain tunkea koodi tänne. Useimpia ei kiinnosta korjata sitä, mutta kysymyksiin ja ongelmiin kyllä saa apua.

Minulla ainakin näyttisi toimivan ihan hyvin, kun laitoin pääfunktion for-silmukkaan tulostuksen näin:

cout << c << " -> " << EC(c,12,avain,5) << " -> " << DC(EC(c,12,avain,5),12,avain,5) << "\n";

Lopputulos näytti minun merkistölläni tältä:

cryptattava -> kµ];g��	���a -> cryptattava
cryptattava -> rµ];~��	���a\Doc� -> cryptattava
cryptattava -> Yµ];U��	���aion � -> cryptattava
cryptattava ->  µ];,��	���aDIA � -> cryptattava
cryptattava -> �µ];���	���ailes� -> cryptattava
cryptattava -> �µ];���	���aE=C:� -> cryptattava
cryptattava -> ýµ];ñ��	���aual � -> cryptattava
cryptattava -> ĵ];��	���aK\v1� -> cryptattava
cryptattava -> £µ];¯��	���a2\os� -> cryptattava
cryptattava -> Šµ];†��	���apl\;� -> cryptattava

Tiedostona, niin löytyvät oudotkin merkit.

Lähinnä tuossa pitää varoa sitä, että ei tule muistivuotoja, ja sitä, että ei kryptatussa käytä merkkejä, joita ei voi tulostaa. Esimerkiksi se nollamerkki katkaisee jonon.

Jtm [24.10.2005 22:40:09]

#

Metabolix sanoi:
"Esimerkiksi se nollamerkki katkaisee jonon"
> Miksi käyttää stringiä - raskasta. Eipä tule tuollaisia ongelmia, jos käyttää ihan char taulukkoa

Metabolix [25.10.2005 11:59:34]

#

Nyt en oikein ymmärtänyt Jtm:n asiaa.

ville-v [25.10.2005 18:44:58]

#

Ilmeisesti Jtm sotkee string-luokan ja char-taulukon keskenään.

Jtm [02.11.2005 18:54:55]

#

ville-v tuolla perusteella edellinen kommenttini olisi ristiriidassa itsensä kanssa

Ette taida siis tietää, ettei char-taulukolla ole esimerkiksi mitään nollamerkki ongelmaa, kuten stringillä on. Jos esimerkiksi lataat tiedoston, jossa on yksikin '\0' eli nollamerkki, stringiin - esim. length/size-funktio ei enää osaa palauttaa stringin pituutta oikein, koska string-luokka käyttää lopetusmerkkinä '\0'

Metabolix [02.11.2005 19:30:20]

#

Jtm: Et tainnut tietää, että kun char-taulun kirjoittaa tekstimuotoiseen tiedostoon <<-operaattorilla, kirjoittaminen loppuu nollamerkkiin. Siksipä, jos aikoo kryptaustaan käyttää tiedostossa muuten kuin koko tiedoston matkalla tai muulla määrätyn mittaisella matkalla, pitää käyttää jotakin, jossa ei pääse tulemaan nollia. Tietenkin jos tiedetään, että tekstiä on tasan 23679 kirjainta, niin silloin voidaan lukea ja kirjoittaa binäärimuodossa sen verran, mutta jos ei tiedetä, niin voi tulla ongelmia.

Ja eihän täällä ole kukaan stringiä käyttänyt. Tässä tapauksessa tiedän kyllä, mistä itse puhun :)

Jtm [02.11.2005 21:57:11]

#

Tietenkin loppuu nollamerkkiin jos talletetaan teksti-muodossa. Mutta jos nollamerkin haluaa mukaan niin tallennetaan suoraan binaarina. Se paljon tiedosto vie tilaa, siitä näkee aina suoraan monta kirjaisinta kryptattava tieto tulee sisältämään. Myös kryptatun tiedon pituus voidaan laskea, sillä kryptaus noudattaa aina tiettyä logiikkaa.

Käytitte epäsuorasti string-tekniikkaa

FooBat [02.11.2005 22:01:12]

#

Kannattaa käyttää fwrite funktiota (stdio.h) tuollaisiin asioihin niin ei tule ongelmia hassujen merkkien kanssa ja tiedostoon päätyy juuri niin monta merkkiä kuin itse haluat.

Metabolix [03.11.2005 18:19:43]

#

Ja sitten muistetaan avata tiedosto muodossa "wb" ja "rb" (tai C++-streameilla ios::binary), etteivät \r ja \n muutu \r\n-pareiksi.

Tuossa kokoasiassa tulee sitten se, että tiedostoon pitää tallentaa myös jokaisen tekstin koko, jos sama tiedosto sisältää useampia tekstinpätkiä. Ja jos kryptausta aikoo käyttää muuallakin kuin omissa binääritiedostoissaan, esimerkiksi PHP-skripteissä tms, niin silloin on syytä tehdä versio, joka käyttää melko rajallista merkkikantaa.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta