Jak wyświetlić zmienną typu unsigned char (1 bajt) w postaci liczbowej?

0

Witam, mam za zadanie pobrać z pliku 16 bajtów danych i je wyświetlić bajt po bajcie czyli przykładowy output mógłby być taki:
screenshot-20181024003834.png
Mój program wygląda następująco:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

#define LEN 16 // 128 bits

int main() {
	unsigned char klucz[LEN]; //tu chcę zapisać to 16 bajtów. 1 komórka tablicy = 1bajt

	FILE *plik = fopen("/dev/urandom", "r");
	fread(klucz, 1, 1, plik);
	fclose(plik);

	int i;
	for(i=0; i<=15; i++) {
		printf("klucz[%d]: %c \n",i,klucz[i]);
	}

	return 0;
}

Niestety efekt jest następujący:
screenshot-20181024004324.png
Wydaje mi się że program próbuje wyświetlić znak przypisany danej liczbie zamist tej liczby. Jak to zmienić?

5

%c służy do wyświetlenia znaku a nie kodu liczbowego. Możesz skorzystać z %u dla liczb bez znaku:

printf("klucz[%d]: %u \n", i, klucz[i]);
5

Przecież na obrazku są liczby szesnastkowe, więc %x.

0

Potrzebuje jeszcze żeby te liczby skleić ze sobą (w formacie hex) i złączyć je z innym napisem. Całość ma tworzyć polecenie i być wywołana w terminalu.
Czyli efekt ma być taki jakby zrobić tak:

system("openssl enc -aes-128-ecb -in plik.txt -out zaszyfrowany.bin -iv 1a5a681493ee7cee59f8ed3bddb6a2");

Tylko zamiast na sztywno wpisanego ciągu "1a5a681493ee7cee59f8ed3bddb6a2" ma być on za każdym razem ładowany wcześniej z tablicy (a do niej z pliku, jak wyżej).

Próbowałem to zrobić tak:

char komenda[300] = "openssl enc -aes-128-ecb -in PLIK -out zaszyfrowany.bin -iv ";
strcat(komenda,klucz);
//system(komenda);
puts(komenda);

Niestety efekt jest taki:

screenshot-20181024233842.png

Niedosyć że liczby przestały być dobrze wypisywane, to w dodatku całość wyświetla się 5 razy zamiast 1 raz i pisze że narusza pamięć. A chciałbym żeby był taki że wypisuje (ostatecznie funkcją system() ) napis:

openssl enc -aes-128-ecb -in plik.txt -out zaszyfrowany.bin -iv 1a5a681493ee7cee59f8ed3bddb6a2
1

Potrzebujesz z grubsza czegoś takiegoś (być może gdzieś jest off-by-one error):

int l = strlen(komenda);
for (int i = 0; i < LEN; ++i) {
    sprintf(komenda + i*2, "%02x", klucz[i]);
}
komenda[l + LEN*2 + 1] = 0;
0

@enedil: To wyświetla tak samo jak zaproponował @Azarien. A ja tak jak pisałem wyżej teraz muszę te liczby połączyć z tekstem żebym mógł całość wstawić jako argument funkcji system(). Nie rozumiem też co robi ostatnia linijka twojego kodu.

2
Erwin14 napisał(a):

@enedil: To wyświetla tak samo jak zaproponował @Azarien.

Nie rozumiesz – to tylko wyświetla dane na ekranie konsoli, a nie zmienia w pamięci liczb na ciągi znaków. Pierwotnie potrzebowałeś wyświetlić liczby w konsoli w postaci heksadecymalnej, do czego służy właśnie format %x, jak słusznie i jako jedyny zauważył @Azarien.

0
furious programming napisał(a):

Nie rozumiesz – to tylko wyświetla dane na ekranie konsoli, a nie zmienia w pamięci liczb na ciągi znaków.

Właśnie rozumiem, tylko to rozwiązanie rozwiązuje problem z 1 postu, ale teraz już nie wystarcza. Bo potrzebuje złączyć te liczby z innym napisem i tej sklejki użyć jako argument funkcji system(). Da się może jakoś przekierować strumień który normalnie byłby wyświetlany żeby trafił do zmiennej?

0

Program już działa, dziękuję za pomoc.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define LEN 16

// użycie: program <nazwa_pliku_in> <nazwa_pliku_out>
int main(int argc, char* argv[]) {

	unsigned char klucz[LEN];

	FILE *plik = fopen("/dev/urandom", "r");
	fread(klucz, 1, 16, plik); //odczytujemy 16 bajtów do klucza
	fclose(plik);

	char kluczDoKomendy[50];
	for (int i = 0; i < LEN; ++i) {
    	sprintf(kluczDoKomendy + i*2, "%02x", klucz[i]);
		//laczymy liczby klucza w postaci heksadecymalnej
	}

	//sklejamy komende
	char komenda[200] = "openssl enc -aes-128-ecb -e -in ";
	strcat(komenda,argv[1]);
	strcat(komenda," -out ");
	strcat(komenda,argv[2]);
	strcat(komenda," -K ");
	strcat(komenda,kluczDoKomendy);

	system(komenda); //wywolujemy ja
	printf("Plik zostal zaszyfrowany. Twoj klucz: %s \n",kluczDoKomendy);
	return 0;
}
1

W swoim rozwiązaniu polegasz na tym, że w char kluczDoKomendy[50] początkowo znajdują się same zera. Nadal potrzebujesz zakończyć stringa zerem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1