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

    +140

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    DWORD H = 0;int i = 0;int S = 1;
    for (i = lstrlen(Stroka)-1; i!= -1; i--)
    {
    H = (H+Stroka[i]*S) % 65535;
    S*=4;
    }
    return H == 0? 65535: H;

    какой-то кустарный хэш.
    не пойму чем пахнет.

    Запостил: bugmenot, 02 Февраля 2011

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

    • Stroka детектед
      Ответить
    • Не нравится мне, когда в условии выхода пишут i != -1.
      Я бы написал i >= 0, так спокойнее. А то мало ли через -1 перепрыгнет и забесконечнится.
      Ответить
      • Это при декременте-то на единицу и правильном начальном условии? :)))
        Ответить
        • У некоторых, вероятно, случается.
          Ответить
        • Ну в данном конкретном случае такая запись будет работать. Но не более.
          Паскалевский фор намного лучше, потому что охраняет от такой херни.
          А адский фор вообще жжот: for i in Stroka'Range loop
          И переменную i не надо объявлять ваще.
          Ответить
          • форыч конечно крут, но иногда в нем не хватает такого счетчика, что бы ответить внутри цикла на вопросы:
            какая ща итерация?
            первая ли?
            или последняя?

            в таких случаях приходится или использовать стандартный фор, или вводить искусственные счетчики\флаги
            Ответить
            • >форыч конечно крут, но иногда в нем не хватает такого счетчика
              Да ладно... foreach(int i in Range(5,15)). Вот и форыч со счётчиком)).
              А вообще троллю. Я Вас понял.
              Ответить
            • Адский фор эквивалентен Паскалевскому (язык-то один, считай), просто может так записываться, чтобы красивее было.
              Поэтому он может ответить на твои вопросы.
              Какая итерация - i
              Первая ли - i = Stroka'First
              Последняя ли - i = Stroka'Last
              Ответить
          • паскалевский фор - гадкий - ни переменную внутри не поменять ни бряк не сделать
            при нормальном форе не надо говнокодить что-то типа
            | i := 0; while(i < n)do begin
            | if ... then break;
            | inc(i);
            | end;
            | if (i < n) ....
            или что-то вроде того.
            | for(i=0; i < n; i ++)
            | if (...) break;
            | if (i < n) ....
            намного лучше.
            Ответить
            • чорт, отступы сожрал :(
              Ответить
            • >паскалевский фор - гадкий
              Берите больше. Паскаль - гад.

              TarasB, я уже становлюсь похожим на Вас? Начинаю толстеть?
              Ответить
              • первые 2-3 года работы на паскале я так и думал:)
                щас напрягает тока корявый фор.
                ну и конечно же отсутствие i ++, ++ i
                даже переменные-в-начале не очень-то напрягают - нефиг писать божественные функции.
                Ответить
                • for(a;b;c) {
                  d;
                  }

                  эквивалентно

                  a;
                  while b do begin
                  d;
                  c;
                  end;

                  А вот
                  for i := a to b do begin
                  c
                  end;
                  не имеет такого наглядного аналога в С++
                  for (i=a;i<=b;i++){
                  c
                  };
                  уже не так абстрактен, посколько имеет лишнюю сущность - операторы неравенства и инкремента.
                  Ответить
                  • да, и b в делфи вычисляется единожды, а тут на каждой итерации
                    Ответить
                  • Паскалеский фор неудобен, тк нельзя использовать результат переменной цикла (она может лишний раз инкрементироваться по выходу из цикла). Приходиться сохранять переменную цикла в промежуточную переменную, если я организовал линейный поиск через фор.
                    Ответить
                    • > тк нельзя использовать результат переменной цикла

                      Ты используешь результат переменной после цикла? Хаха, ты быдлокодер!
                      Ответить
                      • Обычно это плохо, но не всегда.
                        Приведите пример линейного поиска в массиве с получением индекса искомого элемента без оформления его в отдельную функцию.
                        Ответить
                        • > Приведите пример линейного поиска в массиве

                          N := -1;
                          for i := 0 to Length(a) - 1 do if a[i] = Key then begin
                          N := i;
                          Break;
                          end;
                          И сразу ясно, что -1 - это элемент не найден. А Length(a) для ненайденного - это как-то не очевидно.

                          Кстати, массивы не предназначены для поиска.
                          Ответить
                          • >Кстати, массивы не предназначены для поиска.
                            Ещё как предназначены, если там пару элементов.
                            Ответить
                          • >>Кстати, массивы не предназначены для поиска.

                            лолшто???
                            Ответить
                          • >А Length(a) для ненайденного - это как-то не очевидно.
                            Это в паскале. Для
                            for(int i=0;i<Length(a);++i)
                            - Length(a) для не найденного элемента столь же очевидно, как и -1.
                            Ответить
                            • Для малого числа элементов - да.

                              Для
                              > for(int i=0;i<Length(a);++i)
                              - Length(a) для не найденного элемента столь же очевидно, как и -1.

                              Не очевидно. Надо цикл в голове прокрутить, чтобы понять, почему так.
                              Ответить
                              • >Надо цикл в голове прокрутить
                                Тренируйте мозг, что-бы в этом не было необходимости. С такими темпами разжижения мозга Вам скоро придется чип с интерпретатором вживлять, если захотите оставаться программистом.
                                Ответить
                                • Если цикл в голове не прокручивать, то тем более будет неясно.
                                  Мой код более очевиден.
                                  Ответить
                              • нечего тут крутить
                                Ответить
                          • >Кстати, массивы не предназначены для поиска.
                            Вообще то бывают сортированные массивы и даже массивы с расположением элементов дерево. Там и много элементов можно найти достаточно быстро.
                            Ответить
                          • Выходит Д.Кнут был мудак и говнокодер, что написал целый том про поиск и сортировку элементов массива?
                            Ответить
                            • Что Вы! Д.Кнут в Тарасу Б. в подмётки не годится.
                              Ответить
                          • и ЭТО лучше чем
                            for(N = Length(a) - 1; N >= 0; N --) if (a[N] == Key) break;
                            ну-ну!
                            Ответить
                            • TarasB в обратном порядке просмотр массивов ещё не проходил.
                              Ответить
            • > ни переменную внутри не поменять

              Вот и хорошо

              > ни бряк не сделать

              ЛОЛШТО?
              Поставь же что-то новее шестого Турбо Паскаля!
              Ответить
              • Старый паскаль не поддерживает бряки?
                Ответить
                • 6ой Турбо Паскаль не поддерживал ни бряки, ни подсветку синтаксиса. Впрочем, мне это не мешало.
                  Ответить
              • если ставим бряк, то скорее всего нам понадобится переменная цикла, что с паскалевским фор делать нельзя.
                for i := 0 to n - 1 do begin
                if ... then break;
                end;
                if (i < n) .... // тут уже косяк
                т.е. любой поиск в цикле превращается в невесть-что - или лишние переменные объявлять или еще что-ньть в этом роде. да! ОЧЕНЬ удобно! :((
                Ответить
          • В 0x есть. Пам-пам. И с коллекциями заработает.
            Ответить
        • >= быстрее != ?
          Ответить
      • You're not alone.
        Меня подобное тоже всегда почему-то настораживало
        Ответить
      • у вас цикл залупился!
        Ответить
    • А я вам скажу чем это пахнет - это пахнет хуитой.
      Ответить
      • все на этом сайте пахнет почти одинаково
        Ответить
        • Ага, отходами жизнедеятельности программиста :)
          Ответить
          • его мозговой недостаточностью
            его похмельем\недосыпом
            про**анными дедлайнами ))))
            Ответить
    • Ужасный алгоритм хеширования. Жутко небезопасный... Для наглядности, строка размером с символ дак вообще не изменится. =\

      А варианты строк из двух символов соответствующих конкретному хешу вычисляются ну просто элементарно.

      Ну и т.д. Подобрать строку подходящую под хеш можно даже, если изначальная строка была в 10000 символов без каких-либо проблем в считанные миллисекунды.
      Ответить
      • Можно даже попробывать составить алгоритм, который позволит без компьютера вычислять последовательность символов достаточно быстро. Конечно остаток от деления от 65535 (а не 65536) немного усложняет задачу, но не думаю, что принципиально.
        Ответить
      • ээ, это - хеш, а не шифрование с помощью md5
        Ответить
        • Не путайте шифрование и хеширование.
          MD5 - это алгоритм хеширования.

          Если вы хотели сказать, что цель этого алгоритм создавать не безопасный хеш, а ровно-распределённый, то это у автора опять не получилось. Вероятность коллизии между двумя строками из двух символов значительно выше, чем 1/65535
          Ответить
          • Вообще, лично мне в жизни требовалось только два типа хешей:
            1.) Равно-распределённый, для создания ассоциативных алгоритмов и контрольных сумм;
            2.) Криптографический.

            Если вы скажете хороший пример, где может потребоваться какой-то другой тип хеш-функции, то я не удивлюсь, что этот код не подходит и под него ;)
            Ответить
          • Вообще, стоит заметить, что равное распределение вывода от ввода дополнительно усиливает криптостойкость.

            Идеальная лично для меня хеш-функция обладает простыми свойствами:
            1.) Скорость выполнения (от брутфорса можно защититься длинной ключа);
            2.) Ровное распределение на выводе;
            3.) Криптостойкость.
            Ответить
          • капитан в рубке!
            Ответить
      • И подчеркну, что проблема не в том, что хеш ограничен лишь 65535 вариантами возрата, а в самом алгоритме. Пусть даже он был возращал значение из 0 -- (2^64-1), время "дехеша" это особо не увеличело бы
        Ответить
    • А откуда это собственно? :)

      Хочу попробывать воспользоваться столь слабой защитой, если появится возможность)
      Ответить
      • Не путайте хеширование с шифрованием.
        Ответить
        • Я то как раз не путаю, не хочу повторяться, всё уже написал в комментах выше минут за 10 до вашего поста.
          Ответить
          • Ну а для хеширования обратимость хеша односимвольной строки неважна. А правильно подмеченное наличие коллизий двухсимвольных строк противоречит обратимости хеша для них.
            Ответить
            • Ну а как мои посты этому противоречат?.. Они даже вроде как это же и повторяют.
              Ответить
              • К "защите" этот хеш никакого отношения не имеет.
                Ответить
                • Я это и говорю. К "защите" этот хеш алгоритм не имеет никакого отношения. :)

                  И если оно используется в таких целях (что является одним из основных мест применения хеш-функций), то было бы интересно воспользоваться такой возможностью.

                  Просто если задуматься, то данная хеш-функция не имеет отношения ко всем мне известным способам применения хеш-алгоритмов. ;)
                  Ответить
                  • ВНЕЗАПНО -- хеш-таблицы. И прочие случаи, когда при сравнении на неравенство проще сперва сравнить хеш-коды. Основное применение хеш-функций.
                    Ответить
                    • В таких случаях, хороши те хеш-функции, у которых равное распределение значений на выходе. Как я уже говорил ранее, эта хеш-функция такой не является. И как я уже говорил ранее, поэтому и для этого применения она тоже толком не годится.
                      Ответить
    • чота никто не завтыкал на 65535
      сдается мне, что у изобретателя здесь тоже на 1 меньше, чем надо бы...
      Ответить
      • На самом деле это на капельку усиливает алгоритм, и в моих комментах выше на это обращено внимание ;).

        Однако я согласен, что это скорее всего описка, а не задуманка
        Ответить
      • Если бы было 65536, на результат влияли бы только последние 8 символов. Впрочем, и так больше 16 не влияют.
        Ответить

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