Gentoo в продакшене, тем не менее звучит гораздо убедительнее чем любой бинарный дистрибутив. Особенно, если это касается серверных инсталляций. В этом случае количество зависимостей сводится к минимуму. И риск напороться на серьезную проблему при update системы сильно уменьшается. К тому же любой ленивый админ легко организует кэш бинарных сборок на NFS и автоматизирует ежедневное-еженедельное обновление gentoo (разумеется после тестирования на карантином сервере, и да возможно раз в пол года автоматическая сборка не сработает) или воспользуется готовым решением.
В случае бинарных дистрибутивов велик риск привести систему в убитое состояние. Временной период существования известных, не закрытых проблем безопасности, существенно выше.
Правильнее в данном случае использование обычного strcmp. Поскольку константы (const char *) все равно лежат в .rodata, то их повреждение это серьезная ошибка, которую неправильно маскировать применением strncmp.
sizeof(char)==1 Не значит что он занимает ровно один октет, может два и даже 3 на некоторых реально существующих архитектурах (для которых я писал код).
The definition of "byte" is defined in clause 3.4 of ISO/IEC 9899:1990
Basically, a byte is the size of a character. If a character is 16 bits then a byte is 16 bits.
Также автор этой статьи не до конца понимает зачем нужны стандартные типы:
типы (u)intXX_t гарантируют представление знаковых данных в дополнительном коде и размер контейнера
типы (u)int_leastXX_t, а не нестандартные at_leastXX_t гарантируют размер контейнера не менее заказанного
(u)int_fastXX_t гарантируют оптимальное с точки зрения целочисленной арифметики представление данных и размер мантиссы не менее заказанного
Если в каком-то компиляторе они не определены, то это повод сменить компилятор, а при невозможности — исследовать компилируемый код для возможных типов данных и самому определить стандартные типы данных.
В любом случае использование стандартных типов данных (я имею в виду стандарты ISO C) имеет профит при повторном использовании кода по сравнению с использованием всяких непонятных и мутных типов BYTE, PWORD, at_leastXX, s16 и.т.п.
Кроме того грамотный разработчик включает код по контролю размеров и endian типов данных используемых в ABI в процедуры elementarу testing.
Нет правильный перевод на русский это «контрольная сумма фрейма данных» в технологии Ethernet используется FCS32 (совершенно определенный полином), а в X.25 сетях это FCS16 (сами данные в HDLC (который делает bit stuffing в данных для улучшения характеристик более нижних уровней AMI/AMIz/HDB3 etc).
Если говорить об уровнях то в том же ethernеt может быть еще пара уровней в зависимости от конкретной технологии. Сначала манчестер или RLL а потом еще специфичные для среды модуляции. Стандарты только на Ethernet это несколько тысяч страниц IEEE фолианта формата > A4.
У вас в описании полей заголовка TCP, ошибка поле «Urgent pointer» это вовсе не:
Указатель важности. Число, указывающее на важность того или иного пакета.
На самом деле указатель на важные данные это смещение последнего октета важных данных относительно SEQ для пакетов с установленным флагом URG.
В жизни применяется, когда необходимо осуществить контроль потока или состояния протокола верхнего уровня со стороны передающего агента (например, если принимающий агент может косвенно сигнализировать передающему, что не справляется с потоком данных). Большинство реализаций telnet протокола используют механизм urgent data для принудительной очистки буфера полученных, но «не отображенных» данных.
Явно незаслуженно забыт dmesg, syslog, а также данные из procfs, sysfs, debugfs
А вы знаете, что из bash можно сразу отправить строчку в сеть по tcp ли udp через перенаправив вывод в /dev/tcp/$host/$port или /dev/udp/$host/$port?
А еще в bash можно так:
Не совсем так. Для POSIX наличие целочисленных типов intXX_t и uintXX_t с заданными размерами контейнеров 8,16,32 bit обязательно (знаковые обязаны быть в дополнительном коде) «required». 64 bit требуется, если правильно реализован. Все это описано как расширение ISO C.
Я поэтому и взял в кавычки, т.к. в дополнительном коде и паддинга не бывает, а видимо на некоторых архитектурах он есть…
Тут речь шла о том, что нету разницы между int32_t etc и int кроме размера контейнера.
Есть стандарт имплементации языка, если его за годы не прочитали, то это странно.
Посыл про то, что эта оптимизация не нужна тоже мягко говоря странный.
Если программист собирает свои программы с опциями оптимизации, то он должен понимать, что делает и стоит посмотреть, что они подразумевают.
Если он использует новую версию компилятора, то заглянуть в changelog тоже стоит.
Мне вот например не понятно почему для gcc не включена по умолчанию -Wconversion -Wbad-function-cast -Wcast-qual
1. int32_t по сравнению с int по стандарту гарантирует только размер контейнера.
Все целочисленные знаковые типы хранятся одинаково «в дополнительном коде». Платформно зависимо только наличие знака у нулевого значения, значения для неопределенности, и переполнений.
Открываем стандарт ISO C, смотрим, мотаем на ус…
H.2.2 Integer types
1 The signed C integer types int, long int, long long int, and the corresponding
unsigned types are compatible with LIA−1. If an implementation adds support for the
LIA−1 exceptional values ‘‘integer_overflow’’ and ‘‘undefined’’, then those types are
LIA−1 conformant types. C’s unsigned integer types are ‘‘modulo’’ in the LIA−1 sense
in that overflows or out-of-bounds results silently wrap. An implementation that defines
signed integer types as also being modulo need
6.2.6.2 Integer types
1 For unsigned integer types other than unsigned char, the bits of the object
representation shall be divided into two groups: value bits and padding bits (there need
not be any of the latter). If there are N value bits, each bit shall represent a different
power of 2 between 1 and 2N−1, so that objects of that type shall be capable of
representing values from 0 to 2N − 1 using a pure binary representation; this shall be
known as the value representation. The values of any padding bits are unspecified.53)
2 For signed integer types, the bits of the object representation shall be divided into three
groups: value bits, padding bits, and the sign bit. There need not be any padding bits;
signed char shall not have any padding bits. There shall be exactly one sign bit.
Each bit that is a value bit shall have the same value as the same bit in the object
representation of the corresponding unsigned type (if there are M value bits in the signed
type and N in the unsigned type, then M ≤ N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the
following ways:
— the corresponding value with sign bit 0 is negated (sign and magnitude);
— the sign bit has the value −(2M) (two’s complement);
— the sign bit has the value −(2M − 1) (ones’ complement).
Which of these applies is implementation-defined, as is whether the value with sign bit 1
and all value bits zero (for the first two), or with sign bit and all value bits 1 (for ones’
complement), is a trap representation or a normal value. In the case of sign and
magnitude and ones’ complement, if this representation is a normal value it is called a
negative zero.
Это не так, работать будет, но не как Должно.
1. Начнем с того что x[i] это char, а он уже знаковый тип.
2. Далее для в исходном коде константа 27752 а не 27753 как в дизассемблированом. Оба числа не простые, а ближайшее простое 27751.
3. Первый цикл несет абсолютно бессмысленную с точки зрения хэширования операцию 13*27752+x[i] видимо ее добавили для компенсации переполнения на второй итерации.
4. Размер константы 27752 или 27753 на 7 бит больше чем нужно для хэширования, что ведет к большому числу лишних коллизий.
Чтобы работало, как «Должно» нужно привести x[i] к целочисленному типу, далее умножать на максимальное простое число для представления которого достаточно unsigned char или на бит больше (253 или 257 в зависимости от окраски входных данных), для h нужно применить целочисленный тип, которого гарантировано достаточно для хранения результата без переполнения, h нужно инициализировать 0. Потом можно взять результат по модулю 2N где N необходимый порядок выходных слотов или по модулю ближайшего простого числа соответствующему числу выходных слотов хэш функции. Иначе будут лишние неравномерные коллизии.
Еще лучше, конечно, применить стандартные HASH функции выведенные лучшими собаководами.
Проблема приведенного исходного кода от этого никуда не девается.
Нужно использовать без знаковый тип это раз.
Кроме того затычка с проверкой знака, будучи не выкинутой компилятором, увеличивает число коллизий данного хэша в два раза для определенного множества входных строк (или окрашивает спектр для любого множества случайных входных значений, кому так понятнее).
Именно так и надо решать эту задачу.
Для экономии места можно кластеризовать файл с битовой маской присутствия. Хотя в нормальных OS итак поддерживаются sparse файлы и реальный занимаемый объем на FS будет значительно меньше.
Если сделать mmap на этот 1.164GiB файлик или считать его в память то скорость проверки будет на порядки большей чем любое другое решение.
Сам по себе разумный подход к ООП не опасен. Опасность в инструментах, которые слишком многое скрывают от программиста, а их использование обычно означает религию определенного способа мышления и подхода к решению задач.
Лично у меня большие проекты, где основными элементами дизайна (архитектуры) являются сомны сложных объектов вызывающие методы друг друга, а не подсистемы с ограниченным функционалом и конкретным явным уровнем абстракции данных, связанные протоколами различных уровней вызывают головную боль и рвотные позывы.
Особенно когда видишь a++ на верхнем уровне и понимаешь, что сейчас придется пройти через сотню унаследованных классов и операторов, чтобы понять, что здесь происходит :(.
С ротацией IMSI все понятно непонятно, как вы собираетесь обеспечить в конкректной локальной зоне большое количество активных IMSI из своего пула? И даже если предположить гипотетическую возможность этого, как разделить по времени фазу ротации чтобы нельзя было понять что произошло?
А memcpy для строковых констант заменяем на strcpy.
Gentoo в продакшене, тем не менее звучит гораздо убедительнее чем любой бинарный дистрибутив. Особенно, если это касается серверных инсталляций. В этом случае количество зависимостей сводится к минимуму. И риск напороться на серьезную проблему при update системы сильно уменьшается. К тому же любой ленивый админ легко организует кэш бинарных сборок на NFS и автоматизирует ежедневное-еженедельное обновление gentoo (разумеется после тестирования на карантином сервере, и да возможно раз в пол года автоматическая сборка не сработает) или воспользуется готовым решением.
В случае бинарных дистрибутивов велик риск привести систему в убитое состояние. Временной период существования известных, не закрытых проблем безопасности, существенно выше.
Правильнее в данном случае использование обычного strcmp. Поскольку константы (const char *) все равно лежат в .rodata, то их повреждение это серьезная ошибка, которую неправильно маскировать применением strncmp.
sizeof(char)==1 Не значит что он занимает ровно один октет, может два и даже 3 на некоторых реально существующих архитектурах (для которых я писал код).
The definition of "byte" is defined in clause 3.4 of ISO/IEC 9899:1990
Basically, a byte is the size of a character. If a character is 16 bits then a byte is 16 bits.
Также автор этой статьи не до конца понимает зачем нужны стандартные типы:
Если в каком-то компиляторе они не определены, то это повод сменить компилятор, а при невозможности — исследовать компилируемый код для возможных типов данных и самому определить стандартные типы данных.
В любом случае использование стандартных типов данных (я имею в виду стандарты ISO C) имеет профит при повторном использовании кода по сравнению с использованием всяких непонятных и мутных типов BYTE, PWORD, at_leastXX, s16 и.т.п.
Кроме того грамотный разработчик включает код по контролю размеров и endian типов данных используемых в ABI в процедуры elementarу testing.
Если говорить об уровнях то в том же ethernеt может быть еще пара уровней в зависимости от конкретной технологии. Сначала манчестер или RLL а потом еще специфичные для среды модуляции. Стандарты только на Ethernet это несколько тысяч страниц IEEE фолианта формата > A4.
На самом деле указатель на важные данные это смещение последнего октета важных данных относительно SEQ для пакетов с установленным флагом URG.
В жизни применяется, когда необходимо осуществить контроль потока или состояния протокола верхнего уровня со стороны передающего агента (например, если принимающий агент может косвенно сигнализировать передающему, что не справляется с потоком данных). Большинство реализаций telnet протокола используют механизм urgent data для принудительной очистки буфера полученных, но «не отображенных» данных.
А вы знаете, что из bash можно сразу отправить строчку в сеть по tcp ли udp через перенаправив вывод в /dev/tcp/$host/$port или /dev/udp/$host/$port?
А еще в bash можно так:
Кому интересно можно заглянуть сюда
Еще grep, cut, sed, read просто незаменимы при разборе правильно структурированный логов и трейсов…
Поскольку первые ревизии стандартов IEEE Std 1003.1 включали частично стандарты ANSI C, которые давно устарели.
В данный момент все IEEE Std 1003.xx устарели и нужно использовать ISO/IEC/IEEE 9945:2009/Cor 1:2013
Тут речь шла о том, что нету разницы между int32_t etc и int кроме размера контейнера.
Посыл про то, что эта оптимизация не нужна тоже мягко говоря странный.
Если программист собирает свои программы с опциями оптимизации, то он должен понимать, что делает и стоит посмотреть, что они подразумевают.
Если он использует новую версию компилятора, то заглянуть в changelog тоже стоит.
Мне вот например не понятно почему для gcc не включена по умолчанию -Wconversion -Wbad-function-cast -Wcast-qual
Все целочисленные знаковые типы хранятся одинаково «в дополнительном коде». Платформно зависимо только наличие знака у нулевого значения, значения для неопределенности, и переполнений.
Открываем стандарт ISO C, смотрим, мотаем на ус…
1. Начнем с того что x[i] это char, а он уже знаковый тип.
2. Далее для в исходном коде константа 27752 а не 27753 как в дизассемблированом. Оба числа не простые, а ближайшее простое 27751.
3. Первый цикл несет абсолютно бессмысленную с точки зрения хэширования операцию 13*27752+x[i] видимо ее добавили для компенсации переполнения на второй итерации.
4. Размер константы 27752 или 27753 на 7 бит больше чем нужно для хэширования, что ведет к большому числу лишних коллизий.
Чтобы работало, как «Должно» нужно привести x[i] к целочисленному типу, далее умножать на максимальное простое число для представления которого достаточно unsigned char или на бит больше (253 или 257 в зависимости от окраски входных данных), для h нужно применить целочисленный тип, которого гарантировано достаточно для хранения результата без переполнения, h нужно инициализировать 0. Потом можно взять результат по модулю 2N где N необходимый порядок выходных слотов или по модулю ближайшего простого числа соответствующему числу выходных слотов хэш функции. Иначе будут лишние неравномерные коллизии.
Еще лучше, конечно, применить стандартные HASH функции выведенные лучшими собаководами.
Нужно использовать без знаковый тип это раз.
Кроме того затычка с проверкой знака, будучи не выкинутой компилятором, увеличивает число коллизий данного хэша в два раза для определенного множества входных строк (или окрашивает спектр для любого множества случайных входных значений, кому так понятнее).
Для экономии места можно кластеризовать файл с битовой маской присутствия. Хотя в нормальных OS итак поддерживаются sparse файлы и реальный занимаемый объем на FS будет значительно меньше.
Если сделать mmap на этот 1.164GiB файлик или считать его в память то скорость проверки будет на порядки большей чем любое другое решение.
Лично у меня большие проекты, где основными элементами дизайна (архитектуры) являются сомны сложных объектов вызывающие методы друг друга, а не подсистемы с ограниченным функционалом и конкретным явным уровнем абстракции данных, связанные протоколами различных уровней вызывают головную боль и рвотные позывы.
Особенно когда видишь a++ на верхнем уровне и понимаешь, что сейчас придется пройти через сотню унаследованных классов и операторов, чтобы понять, что здесь происходит :(.