Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

operacje na plikach

Ostatnio zmodyfikowano 2012-01-01 18:37
Autor Wiadomość
krzycho89
Temat założony przez niniejszego użytkownika
» 2011-12-30 14:58:04
Nie ogarniam tego.

Więc tak.
Chce stworzyć program który zabezpieczany będzie hasłem, lecz nie typowym hasłem które wpisze w kod aplikacji, tylko taki który wpisuje hasło w zaszyfrowany plik tak aby użytkownik sam mógł sobie je zmienić. Ale nie zdoła tego zrobić w pliku tekstowym dlatego, że w pliku jest ciąg nieużytecznych losowych znaków, a znaki które odpowiadają za hasło będą na wybranych pozycjach tego pliku (użytkownik tych pozycji nie zna). Te pozycje będą znajdować się bezpośrednio (lub kilka znaków dalej) za konkretnymi wymyślonymi przeze mnie łańcuchami znaków. Dlatego aby wyszukać te pozycje postanowiłem stworzyć 2 aplikacje nazwijmy je A1 i A2.

A1 tworzy plik (załózmy ze nazywa się "in.txt" z hasłem czyli dużo losowych znaków miedzy którymi znajduje się wspomniany konkretny ciąg znaków, a za nim jeden ze znaków odpowiadający za hasło. Można to zobrazować na przykład tak:
LLLLLLLLLmmmm(O1)LLLLLLLLLLLLmmmm(O2)LLLLLLLLLmmmm(O3)...
gdzie:
L     -jakiś losowy znak
mmmm  -m wymyślony przeze mnie stały ciąg znaków np "abcd"
(O1)  -jeden ze znaków hasła (konkretny znak wpisany w kod) istnieje więcej (np 3) O1,O2,O3

algorytm działania A1
-otwiera plik którego nie ma (czyli tworzy plik)
-tworzy tablice typu char przechowującą losowe znaki L
{
-losuje znaki dla tabeli funkcją getch() i wypełnia ją
-wpisuje znaki z tabeli do pliku
-wpisuje łańcuch znaków do pliku czyli nasze mmmm
-wpisuje (O1) (później 2)
}<<tak kilka razy (np 3 razy)



A2 to aplikacja która sprawdza czy znaki po mmmm (czyli O)są takie jak były w pliku stworzonym przez A1.
Jak działa A2?
-sprawdza czy istnieje plik stworzony przez A1.
Krok1   Jeżeli NIE to zamknie aplikacje. (bez pliku aplikacja nie działa)
Krok2   Jeżeli TAK to sprawdzi czy "O" są takie jak wprowadziła aplikacja A1
Krok3   jeśli Krok2 TAK to każe wprowadzić nowe hasło i wpisze je do pliku(zamieni znaki oznaczone literą O [O1,O2,O3]))
Krok4   Jeśli Krok2 NIE to każe wprowadzić hasło które kiedyś było wprowadzone przez A2 po jej pierwszym odpaleniu.

Jak sprawdzić czy O są takie jak były?
-otwiera plk
-szuka ciągu (mmmm) znaków opcją find() i zapisuje pozycje na ktorej znajduje sie ten ciąg
-przeskakuje do miejsca w ktorym kończy sie ciąg(mmmm)
-odczytuje O1 (później O2)
-szuka następnego ciągu (mmmm) i jak wyzej odczytuje O2
az odczyta wszystkie i sprawdzi czy były takie same jak A1 to wprowadziła

jeśli nie to karze wprowadzić nowe hasło o analogicznie jak szukanie będzie zapisywało pojedyncze znaki char w miejsca O1,O2,O3

Jestem w fazie tworzenia i odczytywania "O" z pliku in.txt (na razie nie uwzgledniam mozliwosci braku pliku)lecz jak zawsze są problemy.

Nie wiem dlaczego A1 tworząc plik tworzy o 3 znaki za duźo na końcu pliku i są to znaki "@4A" (przynajmniej u mnie na kompie takie są) dlatego stwierdziłem, że może to posłużyć jako mój ciąg "mmmm".

Kody aplikacji wyglądają tak:
A1
C/C++
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>

//aplikacja A1
void wypelnij( char znaki[] )
{
    for( int i = 0; i < 10; i++ ) //petla na wpelnienie wszystkich znakow w tabeli
    {
        char x =( rand() % 93 + 33 ); //losuje znaki (kody ASCII) bez białych znakow i innych ktorych nie chce
        znaki[ i ] = x; //wpisuje znak do tabeli
    }
}

int main()
{
    srand( time( NULL ) );
    std::cout << "Aplikacja do tworzenia plku z haslem\n";
    std::fstream in;
    in.open( "in.txt", std::ios::out ); //tworzy plik (lub otwiera jeśli taki jest)
   
    char znaki[ 10 ]; //tworzy tabele która ma dla celów testowych tylko 10 znaków
    wypelnij( znaki ); //wypelnia tabele
    in << znaki; //wpisuje znaki z tabeli do pliku + to nieszczęsne "@4A" które posluży mi za ciąg "mmmm"
    in.close(); //zamyka plik
    return 0;
} //Aplikacja działa jak trzeba oprócz tego "@4A"


A2
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
//A2
int main()
{
    std::string dane; //tworzy zmienna tekstowa dane
    std::string ciag = "@4A"; //tworzy szukany ciag znakow
    size_t poz_szuk; //tworzy zmienna rpzechowujaca pozycje szukanego ciagu znakow
   
    std::cout << "Program\n";
   
   
    //UWAGA to jest tylko test więc czytam sobie "mmmm" zamiast O1 którego jeszcze nie wprowadzilem w A1
   
   
    std::fstream in; //tworzy in
    in.open( "in.txt", std::ios::out | std::ios::in ); //otwiera plik
    std::cout << "Czy otwarto? " << in.is_open() << "\n"; //sprawdza czy otwarto
   
    std::cout << "Grzie czyta?" << in.tellg() << "\n"; //sprawdza gdzie znajduje sie wskaznik odczytu
   
    in >> dane; //wczytuje zawartosc pliku do zmiennej dane (czy tam kawałekw wiersza)
   
    std::cout << "Grzie czyta?" << in.tellg() << "\n"; //sprawdza gdzie znajduje sie wskaznik odczytu
    poz_szuk =( dane.find( ciag ) ); //szuka pozycji ciągu
   
    in.seekp( poz_szuk, std::ios_base::beg ); //wskaznik przeskakuje w miejsce gdzie zaczyna sie ciag czyli nasze "mmmm"
   
    dane = ""; //resetuje dane zeby potem mi wyswietlilo samo "mmmm"
    std::cout << "Grzie czyta?" << in.tellg() << "\n"; //sprawdza czy przeskoczyl wskaznik
   
    in >> dane; //wczytuje znaki z pliku do zmiennej dane (niestety nie wczytało;/;/
    std::cout << dane; //wypisuje zmienną dane na ekran (czyki nic)
    in.close(); //zamuka plik
    return 0;
} //dlaczego nie wpisalo znaków z pliku do zmiennej dane za 2 razem??

Dlaczego wypisuje to "@4A" w aplikacji A1?
Dlaczego w aplikacji A2 za drugim razem nie wczytuje zawartości pliku do zmiennej chciaż wskaźnik jest na dobrej pozycji?
P-46679
malan
» 2011-12-31 13:03:38
Poświęciłem się i przeczytałem opis Twojego skomplikowanego algorytmu kodującego :)

1.
Dlaczego wypisuje to "@4A" w aplikacji A1?
» Kurs C++Ciągi znaków - łańcuchy lekcja, rozdział Co należy wiedzieć o wczytywaniu tekstu ? analiza przykładu. Podpowiem, że Twoja funkcja wypełnij generuje na przykład coś takiego:
abcdertukd
 i... czegoś tu brakuje :)

2.
Dlaczego w aplikacji A2 za drugim razem nie wczytuje zawartości pliku do zmiennej chciaż wskaźnik jest na dobrej pozycji?
NIE otwieraj pliku do odczytu i zapisu równocześnie:
C/C++
in.open( "in.txt", std::ios::out | std::ios::in ); //otwiera plik
Poza tym - pomieszałeś funkcje/metody. seekp jest dla pliku, do którego zapisujesz dane.

Jak opanujesz już te pliki to przeżuć się na std::ifstream i std::ofstream - wtedy takich błędów nie popełnisz :)
P-46798
krzycho89
Temat założony przez niniejszego użytkownika
» 2012-01-01 17:56:09
Malan, faktycznie brakowało czegoś ;d NULL Diabeł tkwi w szczegółach, a w szególności w programowaniu.

Teraz kod A2 przerobiłem poradziłem sobie z tym drugim odczytywaniem ale otwarłem plik po raz drugi. Kod wygląda tak:
(w komentarzach opisane zmiany)
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
//A2
int main()
{
    std::string dane; //tworzy zmienna tekstowa dane
    std::string dane1;
    std::string ciag = "asdf"; //tworzy szukany ciag znakow
    size_t poz_szuk; //tworzy zmienna rpzechowujaca pozycje szukanego ciagu znakow
   
    std::cout << "Program\n";
   
    std::ifstream in; //tworzy in
    in.open( "in.txt" ); //otwiera plik
    std::cout << "Czy otwarto? " << in.is_open() << "\n"; //sprawdza czy otwarto
   
    std::cout << "Gdzie czyta?" << in.tellg() << "\n"; //sprawdza gdzie znajduje sie wskaznik odczytu
   
    in >> dane; //wczytuje zawartosc pliku do zmiennej dane (czy tam kawa³ekw wiersza)
   
    std::cout << "Gdzie czyta?" << in.tellg() << "\n"; //sprawdza gdzie znajduje sie wskaznik odczytu
    poz_szuk =( dane.find( ciag ) ); //szuka pozycji ci¹gu
   
    in.seekg( poz_szuk, std::ios_base::beg ); //wskaznik przeskakuje w miejsce  gdzie zaczyna sie ciag czyli nasze "mmmm"
   
    dane = "";
    std::cout << "Gdzie czyta?" << in.tellg() << "\n"; //sprawdza czy przeskoczyl wskaznik
    //in>>dane; //<<<<to wyłączyłem
    //std::cout<<dane; //<<<<to wyłączyłem
   
    in.close();
   
    //  \/A to dodałem
    in.open( "in.txt" );
    in.seekg( poz_szuk, std::ios_base::beg );
    in >> dane;
    std::cout << dane;
    in.close();
    return 0;
}

Dwa razy otwieram plik, istnieje inny sposób żeby tego 2 razy nie otwierać??
P-46923
malan
» 2012-01-01 18:37:14
Oczywiście, że można :) Pomyśl logicznie - skoro masz już wszystkie dane* w zmiennej to po co otwierać plik kolejny raz? Zapoznaj się bliżej z klasą std::string, a dokładnie z metodą std::string::substr.

*zakładam, że w pliku nie masz żadnego białego znaku
P-46930
1 « 2 »
Poprzednia strona Strona 2 z 2