Treść zadania:
Napisać krótki program który będzie przeliczał adresy IP pomiędzy postaciami kropkowaną (np. 149.156.74.164), szestnastkową (0x959C4AA4), dziesiętną (2 510 047 908) i binarną (0b10010101100111000100101010100100).
Wcześniej myślałem, że problem rozwiąże tak, że sobie to wrzuce do stringa, odpowiednio podziele wersje kropkowana w tym stringu, rzutuje na inta i zrobie z tego wersje bin i hex (to bylo przy zalozeniu, ze program przyjmuje tylko wersje ip z kropkami). Jednak program ma przyjmować wszystkie wspomniane wersje ip i konwertować na pozostałe... mógłby mi ktoś pomóc?
Ja z takiego IP wyszła taka wersja dziesiętna? Jak to się przelicza?
Przeliczanie IP
Przeliczanie IP
kropki => dziesiętnie
X.Y.Z.T
D= ((X*256+Y)*256+Z)*256+T
dziesiętnie => kropkowo
T=D%256
D/=256
Z=D%256
D/=256
Y=D%256
X=D/256
X.Y.Z.T
D= ((X*256+Y)*256+Z)*256+T
dziesiętnie => kropkowo
T=D%256
D/=256
Z=D%256
D/=256
Y=D%256
X=D/256
-
- Użytkownik
- Posty: 374
- Rejestracja: 21 cze 2007, o 11:28
- Płeć: Mężczyzna
- Lokalizacja: Łostowice
- Pomógł: 146 razy
Przeliczanie IP
Kod: Zaznacz cały
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>
// zamiana liczby 4 bajtowej (int) na ciąg zer i jedynek
char *byte2bin(unsigned ibyte, char* s) {
for(int i = 31; i >= 0; i--) {
if (ibyte % 2)
s[i] = '1';
else
s[i] = '0';
ibyte = ibyte >> 1;
}
s[32] = 0;
return s;
}
// zamiana liczby hexadecymalnej na int
unsigned hex2int(char *shex) {
int ilen = strlen(shex);
unsigned iwynik = 0, ipom;
int ipotega = 0;
for(int i = ilen - 1; (i >= 0) && (shex[i] != 'x'); i--) {
if (shex[i] <= '9') {
ipom = shex[i] - '0';
iwynik = iwynik + (ipom << ipotega);
}
else {
shex[i] = toupper(shex[i]);
ipom = shex[i] - 'A' + 10;
iwynik = iwynik + (ipom << ipotega);
}
ipotega = ipotega + 4;
}
return iwynik;
}
// zamiana ciagu zer i jedynek na int
unsigned bin2int(char *shex) {
int ilen = strlen(shex);
unsigned iwynik = 0;
int ipotega = 0;
for(int i = ilen - 1; (i >= 0) && (shex[i] != 'b'); i--) {
if (shex[i] == '1')
iwynik = iwynik + (1 << ipotega);
ipotega++;
}
return iwynik;
}
int main(int argc, char *argv[]) {
static char *p;
static char s[40]; // zmienna pomocnicza do odczytu
static char spom[9]; // dodatkowa zmienna pomocnicza
union {
unsigned iip; // numer ip jako int
unsigned char tip[4]; // cztery bajty adresu
} liczba;
if(argc != 2) {
printf("Sposob uzycia: %s <numer_ip>\n", argv[0]);
printf("przykład\n");
printf("%s 149.156.74.164\n", argv[0]);
printf("%s 0x959C4AA4\n", argv[0]);
printf("%s 2510047908\n", argv[0]);
printf("%s 0b10010101100111000100101010100100\n", argv[0]);
return 0;
}
strcpy(s, argv[1]);
if (strstr(s, "." )) {
printf("kropkowa %s\n", s);
for (int i = 0; i < 3; i++) {
p = strstr(s, "." );
strncpy(spom, s, p - s);
spom[p - s] = 0;
liczba.tip[i] = atoi(spom);
strcpy(s, p + 1);
}
liczba.tip[3] = atoi(s);
}
else if (strncmp(s, "0x", 2) == 0) {
printf("hex %s\n", s);
liczba.iip = hex2int(s);
}
else if (strncmp(s, "0b", 2) == 0) {
printf("bin %s\n", s);
liczba.iip = bin2int(s);
}
else { // została liczba
printf("dec %s\n", s);
liczba.iip = atoi(s);
}
strcpy(s, "");
printf("%u.%u.%u.%u\n", liczba.tip[0], liczba.tip[1], liczba.tip[2], liczba.tip[3]);
printf("%u\n", liczba.iip);
printf("0x%X\n", liczba.iip);
printf("0b%s\n", byte2bin(liczba.iip, s));
}
Numer IP wersja 4 czyli adres internetowy to liczba 32 bitowa czyli ciąg 32 znaków zero lub jeden.Ja z takiego IP wyszła taka wersja dziesiętna? Jak to się przelicza?
Można go więc wypisać jako ten ciąg czyli 32 bitowa liczba binarna.
Z kolei każde 4 cyfry binarne mogą być zamienione na jeden znak szesnastkowy czyli mamy 8 cyfr szesnastkowych..
Liczba ta może przyjmować wartości od 0 do 2 do potęgi 32 - 1 czyli 4 294 967 295 i właśnie zapis dziesiętny temu odpowiada.
Dla ułatwienia liczbę dzieli się na 4 bajty po 8 bitów każdy i zapisuje się ich wartości od 0 do 255 rozdzielone kropkami.