Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Закодировать и раскодировать ip


Автор: Testernew 23.10.2013, 08:46
Пробую сам но уже 2 дня не могу сделать к своему стыду, и чувство что делаю блин криво как то)) задача закодировать ip адрес к примеру в 5 или 6 значное число а затем с помощью другой функции его раскодировать.... я пробую вот так, что бы запомнить координаты точек(разделителей в ip адресе)) я использую знак '-' но как то коряво выходит... а собрать потом назад этот ip не могу.


Вот мои функции(пишу в MFC): ip из нормального вида в закодированный я перевожу нормально(черточки конечно эти не совсем к стати) а остальное не работает.


Код

CString EncryptIP() {
WSADATA wsa_Data;
int wsa_ReturnCode = WSAStartup(0x101,&wsa_Data);
char szHostName[255];
gethostname(szHostName, 255);
struct hostent *host_entry;
host_entry=gethostbyname(szHostName);
char * szLocalIP;
szLocalIP = inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
WSACleanup();

char tmp[32];
memset(tmp, 0, sizeof(tmp));
strcpy(tmp,szLocalIP);
char res[32]; 
memset(res, 0, sizeof(res));
int ip_points[3]={0,0,0},c=0;
for(int i=0; i < strlen(tmp); i++) {
if(tmp[i] != (char)'.' && tmp[i] != (char)' ') {
res[c] = tmp[i];
c++;
}
if(tmp[i] == '.') {
if(!ip_points[0]) {
ip_points[0] = i;
continue;
}
if(!ip_points[1]) {
ip_points[1] = i;
continue;
}
if(!ip_points[2]) {
ip_points[2] = i;
continue;
}
}    
} 
memset(tmp, 0, sizeof(tmp));
return CString(itoa(atoi(res)/100000,tmp,10))+ _T("-")+CString(itoa(ip_points[0],tmp,10))+ _T("-")+CString(itoa(ip_points[1],tmp,10))+_T("-")+CString(itoa(ip_points[2],tmp,10)); 
}



CString DecryptIP(char str[32]) {
char res[32];
memset(res, 0, sizeof(res));
int ip_points[3]={0,0,0},c=0;

for(int i=0; i < strlen(str); i++) {
if(str[i] != (char)'-' && str[i] != (char)' ') 
res[c] = str[i];
if(str[i] == (char)'-') 
{ 
//res[i]=' ';
ip_points[c]=i;
c++;
}
} 

c=atoi(res) * 100000; 

res[ip_points[0]]=(char)'.';
res[ip_points[1]]=(char)'.';
res[ip_points[2]]=(char)'.';

return CString("some");
}


Как то  бы в этот код вставлять скрытую метку) для обозначения точек в ip.
Если будет время ответь плиз) буду конечно стараться допилить свой вариант.. но а там....

Автор: Randomazer 23.10.2013, 09:03
Переведи каждое число в 16-ю систему счисления.


Цитата

IP ya.ru 

87.250.251.3

57FAFB03



Правда 8 символов будет

Автор: Testernew 23.10.2013, 13:24
Думал в этом направлении но хочется что бы были только цифры.

Автор: Guinness 23.10.2013, 13:44
IPv4 - адрес занимает 4 байта, т.е можно из строки IP-адреса преобразовать к 4 байтовому числу. Как это показал Randomazer.
Цитата(Testernew @  23.10.2013,  09:46 Найти цитируемый пост)
задача закодировать ip адрес к примеру в 5 или 6 значное число а затем с помощью другой функции его раскодировать...

Тут не очень понятно, нужно получить хэш ip-адреса? Насколько мне известно, обратно восстановить ip-адрес не получится.
Можно пояснить, что под этим понимать. Простой пример:
Код

192.168.1.1 -> ? // что хотим получить?

Автор: baldina 23.10.2013, 13:45
http://msdn.microsoft.com/en-us/library/windows/desktop/ms738563(v=vs.85).aspx

Автор: Testernew 23.10.2013, 13:50
Цитата(Guinness @ 23.10.2013,  13:44)
IPv4 - адрес занимает 4 байта, т.е можно из строки IP-адреса преобразовать к 4 байтовому числу. Как это показал Randomazer.
Цитата(Testernew @  23.10.2013,  09:46 Найти цитируемый пост)
задача закодировать ip адрес к примеру в 5 или 6 значное число а затем с помощью другой функции его раскодировать...

Тут не очень понятно, нужно получить хэш ip-адреса? Насколько мне известно, обратно восстановить ip-адрес не получится.
Можно пояснить, что под этим понимать. Простой пример:
Код

192.168.1.1 -> ? // что хотим получить?


На выходе хочу получить просто целое число, чем короче тем лучше.

Автор: baldina 23.10.2013, 13:56
http://ideone.com/pxodmO

Автор: ТарасАтавин 23.11.2013, 14:28
Цитата(Testernew @  23.10.2013,  08:46 Найти цитируемый пост)
задача закодировать ip адрес к примеру в 5 или 6 значное число
Не возможно. При основании 256 адрес четрыхзначен, в любом меньшем основании минимум восьмизначен.

Автор: Фантом 23.11.2013, 14:39
Цитата(ТарасАтавин @  23.11.2013,  15:28 Найти цитируемый пост)
Не возможно. При основании 256 адрес четрыхзначен, в любом меньшем основании минимум восьмизначен.

Ну, положим, не при любом - если, например, основание равно 255, то удастся обойтись пятью знаками.  smile Но, поскольку ТС нужно основание, равное 10, то и знаков понадобится даже не 8, а 10. В общем, поставленная задача не имеет решения.

Автор: ТарасАтавин 23.11.2013, 16:28
Цитата(Testernew @  23.10.2013,  13:24 Найти цитируемый пост)
Думал в этом направлении но хочется что бы были только цифры. 
А что там ещё может быть? Иероглифы?

Добавлено через 1 минуту и 17 секунд
Цитата(Фантом @  23.11.2013,  14:39 Найти цитируемый пост)
Ну, положим, не при любом - если, например, основание равно 255, то удастся обойтись пятью знаками. 
До 254 можно было бы одним, но байт может быть равен 255, значит надо отвести 2. По два на каждый - это 8.

Добавлено через 3 минуты и 2 секунды
Цитата(Фантом @  23.11.2013,  14:39 Найти цитируемый пост)
 Но, поскольку ТС нужно основание, равное 10, то и знаков понадобится даже не 8, а 10.
Во-первых где это сказано? А во-вторых мимально достаточны для представления байта не две с половиной десятичные цифры, а три, 3*4=12.

Автор: Фантом 23.11.2013, 16:41
Цитата(ТарасАтавин @  23.11.2013,  17:28 Найти цитируемый пост)
До 254 можно было бы одним, но байт может быть равен 255, значит надо отвести 2. По два на каждый - это 8.

Зачем?
Цитата(ТарасАтавин @  23.11.2013,  17:28 Найти цитируемый пост)
А во-вторых мимально достаточны для представления байта не две с половиной десятичные цифры, а три, 3*4=12.

Аналогичный вопрос. 

Вы пытаетесь кодировать отдельные байты вместо IP в целом, а это невыгодно. Для представления числа, у которого в системе счисления с основанием 256 не более двух цифр, в десятиричной системе нужно пять цифр (диапазон 0.0 - 255.255 в десятиричной системе соответствует 0 - 65535). Соответственно, достаточно уже не 12 цифр, а 10. Несложно показать, что еще меньше не получится (256^4-1 > 10^9).

Цитата(ТарасАтавин @  23.11.2013,  17:28 Найти цитируемый пост)
Во-первых где это сказано?

Вы только что сами процитировали вот это:
Цитата(Testernew @  23.10.2013,  14:24 Найти цитируемый пост)
Думал в этом направлении но хочется что бы были только цифры. 


Автор: ТарасАтавин 23.11.2013, 18:54
Цитата(Фантом @  23.11.2013,  16:41 Найти цитируемый пост)
Вы пытаетесь кодировать отдельные байты вместо IP в целом, а это невыгодно.
А точки Вам ни о чём не говорят? Это не 4-х байтный инт, это именно 4 байта.

Автор: Фантом 23.11.2013, 19:17
Цитата(ТарасАтавин @  23.11.2013,  19:54 Найти цитируемый пост)
А точки Вам ни о чём не говорят? Это не 4-х байтный инт, это именно 4 байта.

И что?

Разжуем подробнее, раз сходу непонятно. Любому адресу вида A.B.C.D можно сопоставить число N=A*256^3+B*256^2+C^256+D, причем подобное сопоставление будет биекцией (по сути дела, это просто перевод числа, записанного в 256-ричной системе счисления, в 10-ричную). Соответственно, любому возможному IP соответствует некоторое одно число в диапазоне от 0 до 256^4-1=4294967295. Длина обычной десятичной записи таких чисел, очевидно, не превышает 10 знаков.

Автор: ТарасАтавин 24.11.2013, 16:04
Цитата(Фантом @  23.11.2013,  19:17 Найти цитируемый пост)
Разжуем подробнее, раз сходу непонятно. Любому адресу вида A.B.C.D можно сопоставить число N=A*256^3+B*256^2+C^256+D, причем подобное сопоставление будет биекцией (по сути дела, это просто перевод числа, записанного в 256-ричной системе счисления, в 10-ричную). 
Может ещё архиваторы вспомним? Если адресов всего 10 и все внесены в базу, то можно все "закодировать" одноразрядным десятичным индексом, а при двух используемых адресах сжать каждое упоминание до одного бита. А полагается то в смешанную с основаниями 10 и 256.

Добавлено через 3 минуты и 9 секунд
По идее IP - это вообще 
Код
union
{
 structure A
 {
  uint8_t n;
  uint24_t m;
 } a;
 structure B
 {
  uint16_t n;
  uint16_t m;
 } b;
 structure C
 {
  uint24_t n;
  uint8_t m;
 } c;
};
. И не надо валить всё в uint32_t.

Автор: Фантом 24.11.2013, 18:53
Цитата(ТарасАтавин @  24.11.2013,  17:04 Найти цитируемый пост)
Может ещё архиваторы вспомним? Если адресов всего 10 и все внесены в базу, то можно все "закодировать" одноразрядным десятичным индексом, а при двух используемых адресах сжать каждое упоминание до одного бита. А полагается то в смешанную с основаниями 10 и 256.

Хм... Вы вообще что и с кем обсуждаете? 

Автор: xvr 25.11.2013, 14:41
Цитата(Фантом @  24.11.2013,  18:53 Найти цитируемый пост)
Хм... Вы вообще что и с кем обсуждаете?  

Тссс... ТарасАтавин - Специалист с 10ти летним стажем, поэтому ему разрешается нести любой бред невзирая на нас, копошащихся тут у его ног (что он кстати и делает по всему форуму с немалым успехом)  smile 

Автор: bsa 25.11.2013, 14:48
Цитата(ТарасАтавин @  24.11.2013,  17:04 Найти цитируемый пост)
 Если адресов всего 10 и все внесены в базу

Откуда такие данные? ТС про это не писал. Он просто указал, что ему надо IP адрес представить в виде 5-6-значного десятичного числа.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)