- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
static uint ipToUint(byte[] ipBytes)
{
var bConvert = new ByteConverter();
uint ipUint = 0;
int shift = 24; //TODO: указывает количество бит для смещения лево
foreach (byte b in ipBytes)
{
if (ipUint == 0)
{
ipUint = (uint)bConvert.ConvertTo(b, typeof(uint)) << shift;
shift -= 8;
continue;
}
if (shift >= 8)
ipUint += (uint)bConvert.ConvertTo(b, typeof(uint)) << shift;
else
ipUint += (uint)bConvert.ConvertTo(b, typeof(uint));
shift -= 8;
}
return ipUint;
}
Функция конвертирующая массив байтов полученный из IPAddress.Parse("...").GetAddressBytes() в целочисленное представление.
bormand 29.05.2013 10:46 # +4
P.S. Чуть выше, видимо, тоже оптимизация, чтобы плюс лишний раз не гонять.
P.P.S. Неужели в шарпе нет готового класса для хранения ip-адресов и парсера айпишников, поддерживающего как IPv4 так и IPv6?
neeedle 29.05.2013 11:18 # −2
Насчет готового парсера сам искал, нашел такой код:
Но по моему он не правильно работает.
bormand 29.05.2013 11:50 # +2
neeedle 29.05.2013 11:53 # −1
roman-kashitsyn 29.05.2013 11:54 # +3
bormand 29.05.2013 11:57 # 0
Lure Of Chaos 29.05.2013 12:01 # 0
bormand 29.05.2013 12:03 # 0
roman-kashitsyn 29.05.2013 12:05 # +10
myaut 29.05.2013 12:45 # +2
roman-kashitsyn 29.05.2013 13:58 # +5
bormand 29.05.2013 14:02 # +2
fxd
Soul_re@ver 29.05.2013 14:28 # +6
Если за мгновение до катастрофы бортовой компьютер выдаёт segmentation fault то это С.
3.14159265 29.05.2013 17:02 # 0
movaxbx 29.05.2013 13:08 # 0
neeedle 29.05.2013 13:15 # 0
А во вторых, при ручном счете можно проверить и увидеть, что значение не верно.
Для 192.168.1.1 должно быть 3232235777, а получается 33663168.
defecate-plusplus 29.05.2013 13:18 # +1
neeedle 29.05.2013 13:21 # 0
Но в тоже время это как-то странно.
Да кстати, вот проверил, если дописать reverse и toarray то значение больше на единицу чем нужно.
defecate-plusplus 29.05.2013 13:24 # +3
а так, вообще странно, что в с# нет удобного доп. класса а-ля ip::address_v4 / ip::address_v6, с методом типа to_ulong() в v4
притом, что с# конструктор-то сам Int64 принимает, а вот как назад отдать - то только массив
neeedle 29.05.2013 13:27 # 0
neeedle 29.05.2013 13:55 # 0
Мы же передаем для парсинга строку, шарпу никто не мешает распарсить ее и вывести не обратный, а привычный порядок байтов.
defecate-plusplus 29.05.2013 14:27 # +2
он поэтому и называется "сетевой порядок байт"
благодаря этому и писюки, и кофеварки, и утюги, утюги за сапогами, сапоги за пирогами, пироги за утюгами, кочерга за кушаком - т.е. всё то, что можно воткнуть в порт свича, или чем поднасрать в wi-fi эфир - может общаться друг с другом независимо от своей платформы и собственного порядка байт
neeedle 29.05.2013 15:19 # 0
roman-kashitsyn 29.05.2013 15:22 # 0
little endian использует ваша машина для рассчётов.
Да, не сразу очевидно, почему оно называется именно так.
neeedle 29.05.2013 15:30 # −3
Мы отдаем в парсер строку, на выходе получаем массив байтов, там не используются те низкоуровневые представления о которых вы говорите.
roman-kashitsyn 29.05.2013 15:41 # 0
> Все очевидно.
я всего лишь сказал, что IPAddress.Parse().GetAddressBytes() возвращает данные в big-endian, а не в little-endian
neeedle 29.05.2013 16:57 # 0
defecate-plusplus 29.05.2013 17:04 # +1
просто если ты будешь просто рассматривать байты [с0 а8 01 01] как uint32 на little-endian платформе, то получится, что с0 - младший байт, а 01 - старший, и вот ты и получил "ошибочное" представление 0x0101a8c0
почитай уже на педивикии хоть что нибудь про big- и little-endian
neeedle 29.05.2013 17:37 # 0
Вообще то там будет {1,1,168,192}
вот я к чему. Что нельзя было для парсера строк сделать блин big-endian? Еще раз для упрямых, мы отдаем туда строку, блин строку она никак не связана с архитектурой компа и.т.д. Массив элементов типа byte - это не куча байтов!
defecate-plusplus 29.05.2013 17:45 # 0
вот переделанный пример от @roman-kashitsyn
http://ideone.com/sBm4Yr
neeedle 29.05.2013 17:55 # 0
neeedle 29.05.2013 18:10 # −3
В общем косяк в том, что битконвертер конвертирует этот красивый массив { 192, 168, 1, 1 } в неверное целочисленное представление.
Что бы представление было верным нужно сначала перевернуть этот массив, потом создать из него новый массив и только потом посылать битконвертеру. Плюс позже еще и еденичку отнять. Ну вот зачем эти тацны с бубном когда с помощью простого метода или того-же linq это можно сделать быстрее, проще и понятнее. Вот, что я хотел сказать в самом начале.(Для того, что бы целочисленное представление было верным)
А вы пристали тут ко мне со своими байтовыми порядками! Еще запутали и увели в глушь.
defecate-plusplus 29.05.2013 18:30 # +3
neeedle 29.05.2013 20:30 # −2
movaxbx 29.05.2013 18:51 # 0
https://ideone.com/G0qSPF
neeedle 29.05.2013 20:31 # −2
Вопрос в том, что он распарсит не в то число которое должно быть по идее. Что бы получить нужное число приходится допиливать костыли.
movaxbx 29.05.2013 21:08 # +2
>не в то число которое должно быть по идее
Число то, просто оно big-endian, выше уже писали почему.
neeedle 30.05.2013 06:52 # −3
Я теперь попробую еще раз попытаться объяснить.
Массив полученный из функции будет выглядеть так, да? {192, 168, 1, 1}
Тут мы все согласны.
Но вот битконфертер при создании числа пойдет не от головы, а с хвоста. И потому мы получим значение отличное от того, которое вроде бы должны получить.
В общем я против того варианта, с использованием битконвертера, когда нам важно получить целочисленное представление ip-адреса.
movaxbx 30.05.2013 08:02 # +2
neeedle 30.05.2013 10:33 # 0
bormand 30.05.2013 09:22 # +2
3.14159265 29.05.2013 17:08 # +5
Используй LINQ, ёпта.
http://stackoverflow.com/a/2473895
Не слушай всяких смутьянов, которые лезут со своими индейцами.
LINQ решит любые проблемы.
defecate-plusplus 29.05.2013 17:20 # +6
но что-то по ссылке не вижу AsParallel, что за однопоточное говнецо эти гуры там советуют?
3.14159265 29.05.2013 17:39 # +4
inkanus-gray 29.05.2013 22:09 # 0
cyperh 28.02.2014 22:26 # 0
neeedle 28.02.2014 22:40 # 0
roman-kashitsyn 29.05.2013 13:28 # +2
defecate-plusplus 29.05.2013 13:31 # +4
neeedle 29.05.2013 13:33 # 0
defecate-plusplus 29.05.2013 13:42 # +1
neeedle 29.05.2013 13:45 # 0
defecate-plusplus 29.05.2013 13:47 # 0
neeedle 29.05.2013 13:47 # 0
Главное что бы результат не отличался от того, который нужен.
Вот например можно даже из браузера обратится в такому эквиваленту ip адреса и браузер его распарсит.
bormand 29.05.2013 13:54 # −1
roman-kashitsyn 29.05.2013 13:54 # +1
3.14159265 29.05.2013 17:40 # 0
Предпочитаю двухоперандный асм-стайл.
(для любителей антроллить.)
uint res=0
res|=a[0]; res<<=8;
res|=a[1]; res<<=8;
res|=a[2]; res<<=8;
res|=a[3];
movaxbx 29.05.2013 13:20 # 0
0x0201a8c0 == 192.168.1.2
big-endian же
neeedle 29.05.2013 13:25 # −2
Ну не верное же значение.
movaxbx 29.05.2013 13:27 # +1
neeedle 29.05.2013 13:30 # −4
Мы, люди,европейцы, считаем и читаем слева на право.
Так что никакие значения отличные от 3232235777 быть не могут.
roman-kashitsyn 29.05.2013 13:36 # +2
neeedle 29.05.2013 13:39 # −4
Значение должно быть 3232235777 и это проблемы шарпа, не компа.
movaxbx 29.05.2013 13:37 # 0
santa_microbe 29.05.2013 11:25 # +2
Ну собственно в описании к ГК написано, что был использован класс IPAddress и его метод Parse. Ребята просто решили IP в uint перевести, зачем они это делают,я не знаю. Возможно хотят в базе в таком виде хранить, может выборки по диапозонам ip из базы делать будут.
neeedle 29.05.2013 12:03 # 0
Нашел на одном из форумов.
movaxbx 29.05.2013 13:25 # +3
http://stackoverflow.com/questions/4636164/convert-ip-address-into-int-ie-inet-aton-in-c
neeedle 29.05.2013 13:32 # 0
movaxbx 29.05.2013 13:35 # 0
neeedle 29.05.2013 13:37 # 0