1. Си / Говнокод #11440

    +136

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    static int internal_CheckMac(char * inc_mac)
    {
            int return_value = 0x1;
    
            if (strlen(inc_mac) != 17)
            {
                    return return_value;
            }
    
            unsigned int i = 0x0;
            for (i = 3; i <=17; i=i+2)
            {
                    if (inc_mac[i-1] != 58)
                    {
                            return_value = 0x1;
                            break;
                    }
                    else
                            return_value = 0x0;
                    i++;
            }
    
            return return_value;
    }

    Функция проверяет содержимое строки. В строке должен быть мак адрес формата 00:01:02:03:04:05. 58 в строке 13 - это десятичное значение символа ":"
    Авторство функции принадлежит Виталию Кострову, великому программисту из Рыбинска. После ревизии этого кода пришло понимание что надо избавляться от этого сотрудника.

    Запостил: evgeny, 19 Июля 2012

    Комментарии (125) RSS

    • с сотрудниками, как и с работодателем, надо расставаться в хороших отношениях
      код говно, но это меркнет на фоне вашего мужского поступка
      Ответить
      • Давайте не будем обсуждать личные качества конкретного человека. В конце концов за год работы столько лапши было повешено на уши про личные качества этого индивидуума, что мой поступок меркнет в его лучах славы.
        Ответить
        • как же он у вас через собеседование прошел?
          Ответить
          • Чем наглее ложь тем быстрее в нее поверят.
            Ответить
            • обманул компилятор?
              Ответить
            • Если программист заявляет на собеседовании, что он охуенен, это как минимум означает, что ему надо сразу дать решить нетривиальную задачу. Вероятность того, что этот человек абсолютно некомпетентен - 0,(9).
              Ответить
              • Не было большого опыта собеседования.
                Ответить
            • Еще интересно - как он прошел испытательный срок? Ну не верю я, что там все было нормально... А если не было нормально - то виноват уже не сам человек, а тот кто должен был послеживать за ним хотя бы первое время...
              Ответить
              • ... и было бы интересно узнать его фамилию и место жительства
                Ответить
              • Точно так же, как и кодер из моих гк. Не было человека, который мог бы оценить его способности - отдел только создавался.
                Ответить
    • > i=i+2
      > i++;

      > 58

      > 17
      Ответить
    • А вот правильное решение:
      sscanf(addr, "%X:%X:%X:%X:%X:%X", &u8[0], &u8[1], &u8[2], &u8[3], &u8[4], &u8[5]);
      Ответить
    • Код говно как и поступок запостившего.
      Считаю что, ФИО гавнюков(написавших код) не подлежит огласке, в силу программистской этики.

      P.S. "Мудрые обсуждают идеи. Умные — события. Глупые — других людей." (с)
      Ответить
    • Код, конечно, полное говно. Но вам за упоминание ФИО и места жительства человека, написавшего код - минус в карму. Очень неэтичный поступок с вашей стороны.
      Ответить
    • >58
      Виталий Костров, человек и ASCII таблица.
      Ответить
      • Если вместа симвалав пейсать сразу числа, эта ускорит праграмму, веть ей не нада будет каждый раз делать приабразавание!
        Ответить
        • Хм, компилятор что ли ускорится? Программа не компилится же каждый раз перед выполнением :-)
          Ответить
          • Языки разные бывают, в том же PHP текст парсится каждый раз ;)
            Ответить
            • тута вроде Си обсуждают.
              Ответить
            • пыхопроблемы
              Ответить
            • Не совсем. Хотя да, отдельный модуль нужен... Но научили его "компилиться" в некоем роде только 1 раз для нового/изменённого файла. Вполне сносно фурычит, но всё равно время на проверку всех подключенных файлов больше их выполнения. :)
              Ответить
          • Орфография как бы намекает на тег [sarcasm].
            Ответить
        • Паддерживаю, если чилавек пишит сразу код символа, то значит, что он знаит железо и не какой-то ламир!
          Ответить
          • А пачиму канстанта 58 не в хексе? Труъ хакеръ нопесал бы 0x3A.
            Ответить
      • > человек и ASCII таблица

        Однако у вас вышло тоньше всех...
        Ответить
    • int i;
      return sscanf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", &i, &i, &i, &i, &i, &i) != EOF;


      Fixed?
      Ответить
      • Только не !=, а ==. Ведь исходная функция возвращает 0х01 в случае ошибки.
        Ответить
        • Кстати, обратите внимание, что вместо ламерских bool, true, false он использует int , 0x0, 0x1, а это означает, что он знает коды железа, то есть он, возможно, неплохой хакер, поэтому мы его тут обсираем, а он возьмёт, и взломает нас по ойпи.
          Ответить
          • Стандартный bool ведь есть только в C99 и C++.
            Ответить
            • >Стандартный bool ведь есть только в C99

              Тем временем уже есть C11 с генериками...
              Ответить
              • с11? или всё же с++11?
                Ответить
                • сишка же
                  http://www.robertgamble.net/2012/01/c11-generic-selections.html
                  Ответить
                  • _А _Почему _Новое _Слово _Так _Не _В _Тему _Выглядит?
                    Ответить
                    • _Потому что издревле было высечено в камне, что _Все что начинается _С подчеркивания и затем _Большой буквы - зарезервировано
                      чтобы не ломать существующий десятилетиями код, добавили _Вот такое вот новое _Слово, потому что _Имели _Право
                      Ответить
                      • http://talkingabouttheweather.files.wordpress.c om/2012/01/stonecoldirony.jpg
                        Ответить
                      • Чем дальше в лес, тем толще партизаны.
                        По-моему, требование совместимости с архаичными стандартами, что для C, что для C++, делает их с каждым новым обновлением всё менее элегантными. И скоро это превратится в жуткую кашу, если уже не превратилось.
                        Ответить
                        • ну вот как раз в с++ сильно не парились, добавив кучу новых ключевых слов, типа override, final или decltype, где в большинстве случаев совместимость со старым кодом обеспечена семантикой, но вроде как кое-что оно сломать может

                          на самом деле, реальная совместимость старого и нового синтаксиса должна быть разрулена ключами компиляции,
                          а раз ты ССЗБ, что скопипастил старый костыльный код именно в файл с новым синтаксисом - ну значит, не западло будет и исправить руками, никаких уже отмазок "но мы не можем ведь поменять старый код!" уже приниматься не должно
                          Ответить
                          • Я, как пользователь java, торжественно заявляю: молодцы, затрахала уже эта обратная совместимость!
                            Ответить
                      • Ну и из-за этого не-ломать-старый-код получилось уродство.
                        Поменять одно слово (внизапно ставшее ключевым) на другое во всех файлах проекта - говно вопрос, а уродство в языке - навсегда.
                        Ответить
                        • Для _Bool есть bool, а _Generic и так предполагается запихивать в макрос.
                          Ответить
      • проверь на "11:22:33:44:55:6666"
        Ответить
        • Вот зараза.

          Да, scanf - не замена регэкспам.

          Придётся ещё либо strlen, либо все шесть интов проверять на (i == i & 0xff). А это некузяво. :(
          Ответить
          • зачем все шесть
            формат %02x подразумевает, что больше 1 байта не вычитается
            sscanf вернет число успешно распарсенных значений - их должно быть ровно 6
            можно, например, тупо "%02x:%02x:%02x:%02x:%02x:%02x%с", проследить, что либо результат == 6, тогда ок, либо == 7, тогда проверить последний char на isspace
            во всех остальных случаях - не ок

            по поводу регэкспа - если мне будет не лень, напишу тестик
            Ответить
    • ну и еще вполне распространен формат записи через -
      в той же винде, например

      мне сейчас лень искать официальные документы на MAC-48 на предмет регламента записи 6 октетов
      Ответить
    • итак, не поленился, написал сравнение sscanf/boost::regex/boost::xpressive
      под виндой, как обычно, сишные stdio работают супер-шустро, пока не выставишь локаль
      код:
      http://liveworkspace.org/code/b828b89821d56ecf74dd7219bdfe64fd

      на винде результаты:
      test_mac_sscanf : 93 milliseconds
      test_mac_boost_regex : 244 milliseconds
      test_mac_boost_xpressive : 608 milliseconds
      after locale setup......
      test_mac_sscanf : 292 milliseconds
      test_mac_boost_regex : 235 milliseconds
      test_mac_boost_xpressive : 611 milliseconds

      на линухе x86 результаты:
      test_mac_sscanf : 111 milliseconds
      test_mac_boost_regex : 314 milliseconds
      test_mac_boost_xpressive : 3315 milliseconds
      after locale setup......
      test_mac_sscanf : 134 milliseconds
      test_mac_boost_regex : 317 milliseconds
      test_mac_boost_xpressive : 3300 milliseconds

      на линухе x86_64:
      см ссылку на liveworkspace

      выводы -
      1) расхваленный boost::xpressive очень сильно отстает от boost::regex на 32-битном коде, отставание сокращается на х64, но всё равно сильно заметно
      2) строгое ожидание 2 hex символов в октете заставило меня использовать уродское %1x%1x, может я подзабыл все нюансы формата, но я не смог заставить %02x парсить ровно 2 символа, а не не более 2 символов (т.е. он дозволял :a:b: и я это только так поборол)
      3) для boost::regex есть мутные намеки в интернете, что если его перекомпилировать с некими доп. настройками, он будет работать в 2-3 раза быстрее (типа USE_CPP_LOCALE), но если честно, не сильно хочется пробовать
      Ответить
      • интересно, за что минус, может анонимный герой раскроет тайну?
        Ответить
        • небось фанаты boost::xpressive
          Ответить
          • ну я сначала сделал тест без него, потом вспомнил, что вот кто-то же хвалил, мол прирост над его более древним собратом, надо попробовать, и, если честно, не ожидал получить именно такие результаты
            может я его не умею готовить...
            http://bit.ly/NAX1aE - видать инфа о превосходстве борна несколько устарела (Boost.Regex Version: 1.33+, BOOST_REGEX_USE_CPP_LOCALE, BOOST_REGEX_RECURSIVE)
            Ответить
            • Комбинаторы регулярок с проверкой типов... Идея годная. Я бы, правда, предпочёл механизм времени компиляции.
              Ответить
              • Да пожалуйста, только раза в 3 медленнее второго крестоварианта:

                import Text.Parsec
                
                checkMac :: String -> Bool
                checkMac = (const False `either` const True) . runP mac () ""
                
                mac :: Parsec String () ()
                mac = octet >> (macSep ':' <|> macSep '-') >> eof
                    where
                      octet    = count 2 hexDigit
                      macSep c = count 5 $ char c >> octet
                Ответить
                • я правильно понял, что такая "регулярка" (а по сути тут грамматика) будет считать валидным "11-22:33-44:55-66"?
                  кстати еще всплывала мысль запилить тест на boost::spirit, вспомнить молодость так сказать, но на работе иногда и поработать надо
                  Ответить
                  • > а по сути тут грамматика
                    Ага. Но ведь "регулярка" - это тоже некоторая (выбранная ввиду частой встречаемости) грамматика.

                    > будет считать валидным "11-22:33-44:55-66"?
                    <|> пробует левый парсер, если он ничего не смог съесть - переключается правый (развилка без возврата).

                    А здесь по разделителю строится целиком парсер последних 15 символов, вроде все путем.

                    BTW: не подскажите как boost можно прилинковать для быстрой проверки из командной строки?
                    (*.pc нема, не make же файл писать, а то по ошибкам выбирать долго)
                    Ответить
                    • хм
                      линукс для меня не родная система, поэтому если я что то компилю из командной строки, то указать вручную одну директорию поиска и несколько имен в -l не особо напрягает (-L/usr/lib/boost -lboost_system -lboost_regex -lboost_chrono ...)

                      а большие проекты под линухом - там список один раз задан и подставится автоматом

                      если честно, не знаю способа, чтобы код в gcc/ld самостоятельно искал, какие либы он хочет линковать (типа pragma comment lib в студийном тулчейне)
                      Ответить
                    • Буст есть здесь:
                      http://liveworkspace.org/
                      Даже компиляторы и бусты распаковывать себе не придется. Все уже готово онлайново и весьма удобно в онлайновой иде.
                      Ответить
        • Да поди кто-то промазал вместо плюса. Очень уж близко они стоят.

          По теме - интересно, почему на линухе xpressive настолько медленный.

          P.S. На liveworkspace только у меня глючит редактор (пишет символы 2-3 знакоместа правее курсора), когда включена подсветка синтаксиса?
          Ответить
        • Походу там без оптимизаций компилирует, проверил на локалхосте: xpressive всего на 37% дольше regex, без "-O2" - в разы.

          Может за это минуснули, типа "непоказательно"?
          Ответить
      • Интересно, а насколько быстро работает самопал от Виталия?
        Ответить
    • Ай-яй-яй, как нехорошо подсиживать коллегу, говенная атосфера в коллективе детектед, предчуствую жлобоватого вечно злого директора, кучку хомячков трясущихся за свои места и оплеванную курилку...
      Ответить
    • >%02x %04x %0Nx …
      Ага.
      http://v6decode.com/
      2001:0db8:0000:0000:0000:0000:1428:57ab
      201:0db8:0000:0000:0000::1428:57ab
      21:0db8:0:0:0:0:1428:57ab
      1:0db8:0:0::1428:57ab
      2001:0db8::1428:57ab
      2001:db8::1428:57ab


      http://download.dartware.com/thirdparty/test-ipv6-regex.pl
      Ответить
      • напомнило
        #Clinton Pierce
        #note: Requires 5.6.0 or better
        
                            '% * % % * % %<>
                       * % ~ * % % * % * * % *      *
               * % % * *   % * % *<> * % ~   % % % * %
             *  * * % * % % % % * % % % % % % * % % * %
             % * % % ^ * % % % % *[] % % * * % * * % %  %
              % * %   % % % % % * * % * * @ *   @ % * % %
            % ^ % * % * % * * % % * %  <> % % % % * % %() %
          % % * * * % % * % % * * % * * * * % * * % % * * *
           %   * * * % % * % % *[]<> % % % % * % * * * % % *<>
         % * *  % % % * * % * * * \ * %\ * * *   %/ \ # % * *
          % % % *\ * /\ * *// %  %\ <>\ // % %/ % \// % * %
            * * *\ \|| \ \/ / % %// \ \ *\ /<> %//  %// % %<>
           * % * %\  \  |   | ||// % || //  \// % // * * * %
           %{} %  * ----\   \ | /   %||//   /  ---/ / * % % *
             % *  *\ ____\   \| |    /  /  /   /----/ * %
                    \ ----\     |   /   //    /
                           \     \ /        /'
                            =~m/(.*)/s;$_=$1;
                             s![-\\|_/\s]!!g
                               ;%e=('%',0,
                               '^',132918,
                               '~'=>18054,
                               '@'=>19630,
                               '*' =>0b01,
                               '#'=>13099,
                               '[]'=>4278,
                               '<>'=>2307,
                               '{}'=>9814,
                               '()',2076);
                               for $a(keys
                               %e){$e{$a}=
                               sprintf"%b"
                               , $e{$a};}
                             $y= qq{(}.join(
                             '|',map "\Q$_\E"
                           ,keys %e).qq{)};s/$y
                      /$e{$1}/gex;print pack"B*",$_;
        Ответить
      • Какая-то беда с этим ипвшесть. Пхпшники будут плакать, писать велосипеды и массово сходить с ума.
        Ответить
        • Пхпшники будут плакать и массово сходить с ума от вида какой-то фигни вместо ип адреса.
          Ответить
          • Пхпешники плакали, массово сходили с ума, кололись, но продолжали сидеть на пхп.
            >какой-то фигни вместо ойпи адреса
            fixed
            Ответить
        • Никакой беды с ИПв6 нет.
          Просто надо взять и осилить регэкспы, бле@ть!
          Ответить
          • >регэкспы

            Не нужны.
            Ответить
          • Зачем парсить ИПв6 регулярками, если всяко есть готовые библиотеки для этого.
            Ответить
            • А на чём основаны парсеры этих готовых библиотек?
              Ответить
              • ну на самом деле должны быть веские причины заюзать регулярку, найденную на просторах интернетов, либо свой лисапед регэксп на полста строчек (абсолютно неподдерживаемый), вместо системных inet_pton/WSAStringToAddress
                Ответить
                • Так я и не против готовых функций, но за то, чтобы владеть несколькими методами решения одного вопроса. А там уже по обстоятельствам.
                  Ответить
                  • > А на чём основаны парсеры этих готовых библиотек?
                    Да скорее всего тупой конечный автомат. Не думаю, что там будут регулярки.

                    > владеть несколькими методами
                    Безусловно.

                    > А там уже по обстоятельствам.
                    Вот-вот. Написать тот же автомат или регулярку не сложно и не долго. Только вот тот же inet_pton уже отлажен и оттестирован. А с регуляркой все это проходить заново. Так что нужны очень веские обстоятельства, чтобы этим заниматься...
                    Ответить
                    • >нужны очень веские обстоятельства
                      Например лаборатория одного очень не безызвестного дяди умеет определять,
                      что вызывают для своей работы программы безызвестных дядь...
                      Ответить
                      • Не думаю, что продукт одного не безызвестного дяди будет считать подозрительным вызов системной функции для парсинга ipv4/ipv6...
                        Ответить
                        • Продукт одного не безызвестного дяди:
                          1) считает подозрительным по умолчанию всё , если им же(продуктом) не доказано обратное;
                          2) тем более подозрительным всё то, что использует функции из множества «сетевые».

                          Если смотреть немного шире, то по существу, дублирование функционала
                          (естественно, там где это возможно/разумно/etc), несколько усложняет
                          анализ продуктов безызвестных дядь, а значит повышает их шансы на успеваемость.

                          Это всё к тому, что необходимость есть, может и не такая повседневная, но есть.
                          Ответить
                          • Ну да, само собой, если пишешь вирустроянчервькукиспамерыкряки, нефиг пользоваться библиотечными функциями.
                            Ответить
                            • Даже если их не пишешь, общее представление лишним не будет.
                              Ответить
    • весьма интересный подход
      Ответить
      • Поясните пожалуйста, а в чем здесь
        говнокод?
        Как показало обсуждение strlen делать все равно надо.
        А цикл проверки на валидность формата в котором
        представлены данные самый быстрый.
        Сразу возникает вопрос, а была ли поставлена задача
        в данной функции проверять данные записанные в этом
        формате.
        Ответить
    • #include <stdio.h>
      #include <stdbool.h>
      #include <ctype.h>
      
      typedef bool (*validator)(const char);
      
      bool hex_digit_p(const char x)
      {
          char lower_x = tolower(x);
          return ('0' <= x && x <= '9') ||
              ('a' <= lower_x && lower_x <= 'f');
      }
      
      bool colon_p(const char x) { return ':' == x; }
      
      bool mac_address_valid_p(const char* address)
      {
          validator validators[17] =
              {
                  &hex_digit_p,
                  &hex_digit_p,
                  &colon_p,
                  &hex_digit_p,
                  &hex_digit_p,
                  &colon_p,
                  &hex_digit_p,
                  &hex_digit_p,
                  &colon_p,
                  &hex_digit_p,
                  &hex_digit_p,
                  &colon_p,
                  &hex_digit_p,
                  &hex_digit_p,
                  &colon_p,
                  &hex_digit_p,
                  &hex_digit_p
              };
          int i;
          for (i = 0; i < 17; ++i)
          {
              if (!(*validators[i])(address[i]))
                  return false;
          }
          return true;
      }
      
      int main(int length, char** address)
      {
          if (mac_address_valid_p(address[1])) return 0;
          fputs("Mac address ", stderr);
          fputs(address[1], stderr);
          fputs(" is not valid!\n", stderr);
          return 1;
      }

      Так намана, насяльника?
      Ответить
      • Охуеть, массив метапаттернов, записанный в китайском стиле! Этот код должно оценить и быдло, и небыдло
        Ответить
      • Упс, еще нужно было проверить что восемнадцатый символ \x00, но поздно уже.
        Ответить
      • > bool
        Не у всех есть компилятор C99

        > ctype.h
        > hex_digit_p
        isxdigit

        > validator validators[17]
        Создание массива на стеке при каждом вызове функции

        > for (i = 0; i < 17; ++i)
        семнадцать вызовов функций для проверки одной маленькой строки как-то жирновато
        Ответить
        • > Создание массива на стеке при каждом вызове функции

          А компилятор не догадается, что это константа и можно только 1 раз инициализировать?
          Ответить
        • Можно было вынести за пределы функции инициализацию массива, но программа все равно вызывается всего один раз...

          Та ну, в массиве всего 17 элементов... можно и руками заполнить, подумаешь... тем более, что как выяснилось, нужно было бы еще добавить последним номером в этой программе проверку на то, что последний символ таки ноль. Можно было бы написать функцию, которая это делает, но она была бы совсем одноразовой.

          Про компилятор С99... я последний раз писал на Си примерно в том же году... так что извиняйте... я не в курсе последних изменений.

          По поводу проверки - если честно, то не понятно, что именно мы проверяем, т.как у МАК адресов нет задокументированой печатной формы, есть только общие какие-то "пожелания", где говорится что, например, можно использовать значек переноса вместо двоеточия, но я не видел ни одного примера где бы использовались одновременно и двоеточия и переносы. Изза чего не понятно можно ли допускать и то и другое одновременно.

          Что до ipv6, то там вообще, как обычно, жопа полная в смысле написания и расшифровки. Там возможно 17 вызовами не обойтись. Как-то инженерная озадаченная сила любит озадачивать оставшуюся часть незадачливого человечества всякой херней в духе электорпочтовых адресов, универсальных идентификаторов в интернете и т.п. Этот совсем даже не исключение.
          Ответить
      • Вот так, насяльника нужно:
        #include <functional>
        #include <string>
        #include <algorithm>
        #include <ctype.h>
        
        using namespace std;
        
        bool mac_address_valid_p(string address)
        {
            function<bool(char)> validators[] =
                {
                    ::isxdigit,
                    ::isxdigit,
                    [](char x){return ':' == x;}
                };
            bool r;
            return address.end()!=find_if(address.begin(), address.end(), [&](char x)
            {
               return
               (
                  r=validators[0](x),
                  rotate(begin(validators), end(validators)-1, end(validators)),
                  r
               );
            });
        }
        Ответить
        • Проверку длины address забыл добавить в начале функции. У автора кода выше - таже ошибка.
          Ответить
          • Автор кода выше честно в этом признался, выше.
            Ответить
        • >return
          > (
          > r=validators[0](x),
          > rotate(begin(validators), end(validators)-1, end(validators)),
          > r
          > );
          Хахах. Что только не сделают крестушки, чтобы использовать вывод типа результата лямбды и не указывать его вручную. Haskell чтоле возьми.
          Ответить
          • Сишечка, а похоже на функциональный язык. Мне нравится. Вертает результат функции последней строкой. :)
            Ответить
        • Вообще какбы было бы не плохо rotate сделать в виде итератора, но только чтобы было также кратко. Может в бусте что есть?
          Ответить
        • Это у тебя самая маленькая реализация на крестах без регэкспов и граматик?
          Можно было обойтись и без тежолой function<bool(char)>
          Ответить
          • А тут короче на крестах и не сделаешь.
            Ответить
        • KISS
          #include <ctype.h>
           
          static const char mac_pattern[] = "xx:xx:xx:xx:xx:xx";
           
          int well_formed_mac(const char *str)
          {
            const char *c, *p;
            for (c = str, p = mac_pattern; *c && *p; ++p, ++c) {
              switch (*p) {
              case 'x':
                if (!isxdigit(*c)) return 0;
                break;
              default:
                if (*p != *c) return 0;
              }
            }
            return *c == *p;
          }
          http://ideone.com/S2zZZ
          Никаких проблем с длиной.
          Ответить
          • Красивый и быстрый код ;) Кстати раз уж код не претендует на обобщенность (mac_pattern впилен внутрь), то можно заменить двухпозиционный switch на if...

            P.S. Сорри, хотел плюсануть, а попал в минус.
            Ответить
            • > Красивый и быстрый код
              я старался
              > не претендует на обобщенность
              хотел намекнуть, что микро-язык можно легко расширить и принимать шаблон как параметр, но делать этого не стал.
              > Сорри, хотел плюсануть, а попал в минус
              У меня, кстати, родилась вот какая идея для клона гк:
              заменить плюсы и минусы битовыми сдвигами
              >>   2^1   <<
              только не совсем понять, как быть с отрицательным рейтингом... или так
              --    1    ++
              Ответить
              • > как быть с отрицательным рейтингом
                Двоичной дробью.
                Ответить
          • KISSer
            #include <ctype.h>
            bool well_formed_mac(const char *str)
            {
              static const char mac_pattern[] = "xx:xx:xx:xx:xx:xx";
              for (const char *c = str, *p = mac_pattern; *c && *p; ++p, ++c)
                if(*p=='x' && !isxdigit(*c) || (*p != *c))
                  return 0;
              return *c == *p;
            }


            P.S. Сорри, хотел плюсануть, а попал в минус. Проклятье минуса. :\
            Ответить
            • Скобки не там поставил:
              if((*p=='x' && !isxdigit(*c)) || *p != *c)
              fixed
              Ответить
            • Лямбды, хуямбды. А опять все соснули у олдскульной и примитивной императивщины.
              Ответить
              • Кратко, но думаю этот код плохо читабильный \ плохо поддерживаемый.
                Ответить
                • >плохо читабильный
                  "xx:xx:xx:xx:xx:xx"

                  В отличие от Хацкильного варианта и magic number проверок длины.
                  Ответить
        • Фу как много кода, на хаскеле то это всего 2 строчки:
          validators = cycle [isHexDigit, isHexDigit, (==':')]
          mac_address_valid_p address = and $ zipWith id validators address
          Ответить
          • Только вот примет 11:11:11:11:11:11:11:11:11:11:11:11:11:1 1:11:11:11
            Ответить
            • Я для наглядности повторил багу автора выше. Он же тоже повторил. Видимо это модно.
              Ответить
            • >Только вот примет 11:11:11:11:11:11:11:11:11:11:11:11:11:1 1:11:11:11
              Не примет. У тебя там лишний пробел. :D
              Ответить
              • Этот пробел писал не я, это движок гк длинные строки рубит для переноса ;(
                Ответить
                • кстати, видимо рубит исходя из ширины монитора разработчика
                  Ответить
    • Сначала было сделал так:
      import Data.Char
      validators = cycle [isHexDigit, isHexDigit, (==) ':']
      correctMac address =    if length address /= 17 then 
                                      False
                              else
                                      foldl (&&) True (zipWith (\v x -> v x) validators address)
      Ответить
      • Потом переписал на более функциональный стиль:
        import Data.Char
        validators = cycle [isHexDigit, isHexDigit, (==':')]
        correctMac address = case length address of 
                                17      -> and $ zipWith id validators address
                                _       -> False
        Ответить

    Добавить комментарий