• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Ukryta wiadomość w strukturze.

Object Storage Arubacloud
0 głosów
1,064 wizyt
pytanie zadane 27 maja 2020 w C i C++ przez pozdro600 Początkujący (260 p.)

Mam do wykonania zadanie:

Przygotuj program do ukrywania wiadomości w nieużywanych częściach struktur języka C, przy założeniu, że struktury nie są upakowane.

W tym celu przygotuj strukturę do przechowywania trzech wartości typu char, double i int w podanej kolejności. Struktura powinna wyglądać następująco:

struct message_t
{
    char a;
    double b;
    int c;
};

Domyślnie kompilator języka C optymalizuje kod programu pod kątem szybkości dostępu do pól struktury, a nie pod kątem miejsca przez nią zajmowanego.

Oznacza to, że rozmiar poniższej struktury wynosi 24 bajty, przy czym dane zajmują tylko 13 bajtów. Różnica - 11 bajtów - jest niewykorzystana i można tam ukryć wiadomość.

Przygotuj funkcję do odczytywania wiadomości ukrytej na niewykorzystanych bajtach sekwencji struktur message_t oraz funkcję do wczytywania tablicy struktur message_t z pliku. Przygotowane funkcje powinny mieć następujące prototypy:

int load_data(struct message_t *cp, int size, const char *filename);

Funkcja ma za zadanie wczytać dane z pliku filename to tablicy struktur cp o pojemności size struktur message_t.

Parametry:

  • filename - nazwa pliku, z którego mają zostać odczytane dane.
  • cp - wskaźnik na tablicę struktur,
  • size - rozmiar tablicy struktur.

Struktura pliku:

Struktura wczytywanego pliku wygląda następująco:

  • liczba n bajtów danych od odczytania (pole unsigned int), następnie
  • n bajtów, które mają tworzyć zawartość struktur message_t.

Wartość n=24 to jedna struktura message_t, 48 to dwie, itd. Wartość niebędąca wielokrotnością długości struktury jest niedopuszczalna.

Wartość zwracana:

  • >0 - w przypadku powodzenia - liczba wczytanych struktur,
  • -1 - w przypadku przekazania do funkcji błędnych danych,
  • -2 - w przypadku niepowodzenia otworzenia pliku lub
  • -3 - w przypadku, kiedy w pliku są uszkodzone dane.

W przypadku, kiedy w pliku znajdzie się więcej danych, niż można zmieścić w tablicy struktur, funkcja powinna wczytać tyle danych ile jest możliwe.


int decode_message(const struct message_t *cp, int size, char *msg, int text_size);

Parametry:

  • cp - wskaźnik na tablicę struktur, w których ukryta jest wiadomość,
  • size - rozmiar tablicy struktur,
  • msg - wskaźnik na tablicę znaków, do której ma zostać zapisana wiadomość wydobyta z sekwencji struktur message_t,
  • text_size - rozmiar tablicy znaków (pojemność w bajtach).

Wartość zwracana:

  • 1 - w przypadku podanie błędnych danych wejściowych lub
  • 0 - w przypadku poprawnego odczytania wiadomości.

Napisz program, który pobierze od użytkownika nazwę pliku (nie więcej niż 30 znaków), a następnie odczyta z niego struktury oraz odczyta ukrytą w nich wiadomość.

W przypadku, kiedy nie można otworzyć pliku program powinien wyświetlić komunikat Couldn't open file i zakończyć działanie z kodem błędu 4. W przypadku kiedy dane w pliku są zapisane niepoprawnie, program powinien wyświetlić komunikat File corrupted i zakończyć działanie z kodem błędu 6.

W przypadku poprawnego odczytania pliku, program powinien wyświetlić na konsoli treść odczytanej wiadomości bez żadnych dodatkowych znaków w wierszu.

Przykładowa interakcja z programem -- sukces:

Pliki: 2420test1.bin

Enter file name: 2420test2.bin⏎
I'm fascinated by the idea that genetics is digital. A gene is a long sequence of coded letters, like computer information. Modern biology is becoming very much a branch of information technology. - Richard Dawkins

Oto moje rozwiązanie:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
struct message_t
{
    char a;
    double b;
    int c;
};

int load_data(struct message_t* cp, int size, const char* filename) {
    if (filename==NULL||cp==NULL) {
        return -1;
    }
    if (size<1) {
        return -1;
    }
    unsigned char* ptr = (unsigned char*)cp + 0;
    FILE* fp;
    fp = fopen(filename, "rb");
    if (fp == NULL) {
        return -2;
    }
    fseek(fp, 0, SEEK_END);
    int x=ftell(fp);
    if (x == 0) {
        fclose(fp);
        return -3;
    }
    fseek(fp, 4, SEEK_SET);
    int i = 0;
    
    while (feof(fp) == 0&&i<=size) {
        if (ferror(fp) != 0) {
            return -3;
        }
        x = fread(ptr, 1, 1, fp);
        if (x != 0 && x != 1) {
            break;
        }
        if (x == 0) {
            break;
        }
        ptr++;
        x = fread(ptr, 1, 7, fp);
        if (x != 0 && x != 7) {
            return -3;
        }
        if (x == 0) {
            return -3;
        }
        ptr += 7;
        x = fread(ptr, 1, 8, fp);
        if (x != 0 && x != 8) {
            return -3;
        }
        if (x == 0) {
            return -3;
        }
        ptr += 8;
        x = fread(ptr, 1, 4, fp);
        if (x != 0 && x != 4) {
            return -3;
        }
        if (x == 0) {
            return -3;
        }
        ptr += 4;
        x = fread(ptr, 1, 4, fp);
        if (x != 0 && x != 4) {
            return -3;
        }
        if (x == 0) {
            return -3;
        }
        ptr += 4;
        i++;
        cp++;
        ptr = (unsigned char*)cp;
    }
    if (fclose(fp) == EOF) {
        return -3;
    }
    return i;
}
int decode_message(const struct message_t* cp, int size, char* msg, int text_size) {
    if (size <1||size>100 || msg == NULL || cp == NULL||text_size<1) {
        return 1;
    }

    unsigned char* ptr = (unsigned char*)cp+0;
    int i = 0, x=0;
    while (isalpha(*ptr) == 0 && isdigit(*ptr) == 0) {
        ptr++;
    }
    while (1) {
        if (i == size) {
            *msg = '\x0';
            break;
        }
        i++;
        ptr++;
        if (x + 7 >= text_size-1) {
            memmove(msg, ptr, text_size-1-x);
            msg += text_size-1-x; 
            *msg = '\x0';
            break;
        }
        memmove(msg, ptr, 7);
        x += 7;

        msg += 7;
        ptr += 19;
        if (x + 4 >= text_size) {
            memmove(msg, ptr, text_size-x-1);
            msg += text_size-1-x;
            *msg = '\x0';
            break;
        }
        memmove(msg, ptr, 4);
        x += 4;
        if (x >= text_size) {
            *msg = '\x0';
            break;
        }
        msg += 4;
        ptr += 4;
        if (*(ptr-1) == '\x0' || *ptr == '\x0') {
            *msg = '\x0';
            break;
        }
     
    }
    return 0;
}
int main(){
    struct message_t t[100];
    puts("Enter file name:");
    const char str[3000];
    char tab[31], c;
    int i = 0;
        while (1) {
        if (scanf("%c", &c) == 0) {
            printf("Incorrect input");
            return 1;
        }
        if (i > 29) {

        }
        else {
            if (c == '\n') {
                break;
            }
            *(tab + i) = c;
            i++;
        }
    }
        *(tab + i) = '\x0';
        FILE* fp;
        fp= fopen(tab, "r");
            if (fp == NULL) {
        printf("Couldn't open file");
        return 4;
    }
            fclose(fp);
        i = 0;

        int y = load_data(t, 100, tab);
        if (y == -3) {
            printf("File corrupted");
            return 6;
        }
        decode_message((const struct message_t*)t, 100, (char*)str, sizeof(str));
        printf("%s", str);
  
    return 0;
 }

 

zrobiłem juz całe zadanie natomiast moja funkcja "load_data" powinna zwracać '-3', przy uszkodzonym pliku a tego nie robi domyślam się ze jest to związane z tą częscią polecenia której kompletnie nie rozumiem:

Struktura pliku:

Struktura wczytywanego pliku wygląda następująco:

  • liczba n bajtów danych od odczytania (pole unsigned int), następnie
  • n bajtów, które mają tworzyć zawartość struktur message_t.

Wartość n=24 to jedna struktura message_t, 48 to dwie, itd. Wartość niebędąca wielokrotnością długości struktury jest niedopuszczalna.

 

Szczególnie chodzi mi o 2 pierwsze podpunkty.

komentarz 27 maja 2020 przez j23 Mędrzec (194,920 p.)
edycja 27 maja 2020 przez j23
    fseek(fp, 0, SEEK_END);
    int x=ftell(fp);
    if (x == 0) {
        fclose(fp);
        return -3;
    }
    fseek(fp, 4, SEEK_SET);
    int i = 0;

Po co te zabiegi? W opisie masz napisane, że pierwsze 4 bajty to ilość zawartych w pliku danych wyrażona w bajtach.

Tak to widzę:

int load_data(struct message_t* cp, int size, const char* filename)
{
    if (filename == NULL || cp == NULL || size < 1) {
        return -1;
    }

    FILE* fp = fopen(filename, "rb");
    if (fp == NULL) {
        return -2;
    }

    unsigned int n;

    if (fread(&n, sizeof(unsigned int), 1) != 1) {
        fclose(fp);
        return -3;
    }

    n /= sizeof(message_t);

    if (n > size) n = size;
    else size = n;

    while (n-- > 0 && fread(cp++, sizeof(message_t), 1, fp) == 1) {}

    if (feof() != 0 || ferror(fp) != 0) {

        fclose(fp);
        return -3;
    }

    fclose(fp);
    return size;
}

 

komentarz 27 maja 2020 przez pozdro600 Początkujący (260 p.)
Uratowałeś mnie, wielkie dzięki! :)

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
0 odpowiedzi 559 wizyt
pytanie zadane 30 kwietnia 2020 w C i C++ przez fortuna Początkujący (310 p.)
0 głosów
1 odpowiedź 620 wizyt

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...