1. C++ / Говнокод #26357

    +3

    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
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    // https://habr.com/ru/post/451830/  Кратко с реализацией о AES 128 ECB
    
    // ...
    
    byte_t hex(char ch) { return (ch - '0') % 39; }
    byte_t sbox(byte_t x, bool decrypt = false) {
      std::string s = (decrypt ? INV_SBOX : SBOX)[x >> 4][x & 15];
      return hex(s[0]) << 4 | hex(s[1]);
    }
    byte_t mult_by_2(byte_t x) { return (x < 128) ? x << 1 : (x << 1 & 0xff) ^ 0x1b; }
    byte_t mult_by_8(byte_t x) { return mult_by_2(mult_by_2(mult_by_2(x))); }
    
    const std::unordered_map<byte_t, std::function<byte_t(byte_t)>> mapper = {
      {0x1, [](byte_t x) { return x; }},
      {0x2, mult_by_2},
      {0x3, [](byte_t x) { return mult_by_2(x) ^ x; }},
      {0x9, [](byte_t x) { return mult_by_8(x) ^ x; }},
      {0xb, [](byte_t x) { return mult_by_8(x) ^ mult_by_2(x) ^ x; }},
      {0xd, [](byte_t x) { return mult_by_8(x) ^ mult_by_2(mult_by_2(x)) ^ x; }},
      {0xe, [](byte_t x) { return mult_by_8(x) ^ mult_by_2(mult_by_2(x)) ^ mult_by_2(x); }},
    };
    byte_t vector_mult(const std::array<byte_t, 4>& v1, std::array<byte_t, 4>&& v2) {
      std::transform(begin(v1), end(v1), begin(v2), begin(v2),
        [](byte_t x, byte_t y) { return mapper.at(y)(x); });
      return std::accumulate(begin(v2), end(v2), byte_t(0), std::bit_xor<byte_t>());
    }
    
    
    const std::vector<std::vector<std::string>> SBOX = { // блядь сука долбоеб нахуя это так делать?
      { "63", "7c", "77", "7b", "f2", "6b", "6f", "c5", "30", "01", "67", "2b", "fe", "d7", "ab", "76" },
      { "ca", "82", "c9", "7d", "fa", "59", "47", "f0", "ad", "d4", "a2", "af", "9c", "a4", "72", "c0" },
      { "b7", "fd", "93", "26", "36", "3f", "f7", "cc", "34", "a5", "e5", "f1", "71", "d8", "31", "15" },
      { "04", "c7", "23", "c3", "18", "96", "05", "9a", "07", "12", "80", "e2", "eb", "27", "b2", "75" },
      { "09", "83", "2c", "1a", "1b", "6e", "5a", "a0", "52", "3b", "d6", "b3", "29", "e3", "2f", "84" },
    // ...

    пиздец нахуй

    Запостил: j123123, 16 Января 2020

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

    • > В продакшене точно не нужно использовать данную реализацию. Поинт статьи — показать, что алгоритм (aes 128) весьма прост.

      Поинт статьи — показать как можно нагородить на ровном месте какого-то тупого и бессмысленного крестодерьма.
      Ответить
    • > нахуя это так делать

      Противодействие атакам, которым подвержены наивные реализации AES. Пока строка скопируется да распарсится - уже все тайминги размыты и кеш засран.
      Ответить
    • Еба-а-ать, в каждой ёбанной строке — говно!

      > byte_t hex(char ch)
      Сука, SBOX в строках хранить не лень, а лишний раз нажать кнопочки и дать адекватное название функции — не лень.
      > return (ch - '0') % 39
      Ой бля.
      > [x >> 4][x & 15]
      Почему, сука, 15? Неужели так трудно писать так, чтобы тебя понимали? «x & 0x0F» — и сразу становится понятно, что автор имел в виду.
      > mult_by_2
      Ну вот, более-менее адекватное название функции!
      > return (x < 128) ? x << 1 : (x << 1 & 0xff) ^ 0x1b;
      …чо, бля?
      > const std::unordered_map<byte_t, std::function<byte_t(byte_t)>>
      Ебать нахуй ебать!..
      > mapper
      Какое точное и информативное название.
      > const std::array<byte_t, 4>
      Я такое пишу когда мне хочется повыёбываться и высрать максимально запутанное крестоговно. А автору норм.
      > && v2
      Знакомые симптомы: аффтар где-то вычитал, что двойные амперсанды быстрее одинарных, и теперь везде их суёт, совершенно не понимая, что это и зачем оно нужно. Ничего не напоминает?
      > begin(v1), end(v1), begin(v2), begin(v2)
      Именно поэтому я против «begin(STL), end(STL)».
      > [](byte_t x, byte_t y) { return mapper.at(y)(x); }
      «Как проебать любые оптимизации и написать тормозное говно, том 7».
      > const std::vector<std::vector<std::string>> SBOX
      Пизде-е-е-е-е-е-е-ец. Ну хоть бы std::array, блядь!..

      Тупое говно тупого дебила.
      Ответить
      • >> return (ch - '0') % 39

        Кокококой скилл )))

        Если ch > '9', то из кода заглавных букв нужно дополнительно вычесть 7, а из кода строчных — 7 + 32 = 39, чтобы перевести 'a'...'f' в 10...15.

        Код с задачей преобразования строчных 16-ричных символов в число справляется. Только обычный человек до операции взятия остатка не додумается.
        Ответить
        • Таблица результатов для ANSKILL-символов:
          ' ' => -16
          '!' => -15
          '"' => -14
          '#' => -13
          '$' => -12
          '%' => -11
          '&' => -10
          ''' => -9
          '(' => -8
          ')' => -7
          '*' => -6
          '+' => -5
          ',' => -4
          '-' => -3
          '.' => -2
          '/' => -1
          '0' => 0
          '1' => 1
          '2' => 2
          '3' => 3
          '4' => 4
          '5' => 5
          '6' => 6
          '7' => 7
          '8' => 8
          '9' => 9
          ':' => 10
          ';' => 11
          '<' => 12
          '=' => 13
          '>' => 14
          '?' => 15
          '@' => 16
          'A' => 17
          'B' => 18
          'C' => 19
          'D' => 20
          'E' => 21
          'F' => 22
          'G' => 23
          'H' => 24
          'I' => 25
          'J' => 26
          'K' => 27
          'L' => 28
          'M' => 29
          'N' => 30
          'O' => 31
          'P' => 32
          'Q' => 33
          'R' => 34
          'S' => 35
          'T' => 36
          'U' => 37
          'V' => 38
          'W' => 0
          'X' => 1
          'Y' => 2
          'Z' => 3
          '[' => 4
          '\' => 5
          ']' => 6
          '^' => 7
          '_' => 8
          '`' => 9
          'a' => 10
          'b' => 11
          'c' => 12
          'd' => 13
          'e' => 14
          'f' => 15
          'g' => 16
          'h' => 17
          'i' => 18
          'j' => 19
          'k' => 20
          'l' => 21
          'm' => 22
          'n' => 23
          'o' => 24
          'p' => 25
          'q' => 26
          'r' => 27
          's' => 28
          't' => 29
          'u' => 30
          'v' => 31
          'w' => 32
          'x' => 33
          'y' => 34
          'z' => 35
          '{' => 36
          '|' => 37
          '}' => 38
          '~' => 0
          Ну или если считать char беззнаковым, то несколько первых строчек будут выглядеть так:
          ' ' => 6
          '!' => 7
          '"' => 8
          '#' => 9
          '$' => 10
          '%' => 11
          '&' => 12
          ''' => 13
          '(' => 14
          ')' => 15
          '*' => 16
          '+' => 17
          ',' => 18
          '-' => 19
          '.' => 20
          '/' => 21
          Ответить
      • >> begin(v1), end(v1), begin(v2), begin(v2)
        > Именно поэтому я против «begin(STL), end(STL)».
        У них же уже есть initializer list, variadic templates и ещё какая-то питушня с распаковкой массивов зачаточным паттерн матчингом вылупляется.
        Почему бы тогда не сделать operator argument_list?
        Для ко-ко-контейнеров он бы возвращал {begin(xs), end(xs)} и прозрачно вставлялся.

        Было бы так (при условии, что код std::transform никак не поменялся:
        std::transform(v1, v2, pituz); // при компиляции раскрываются все кобенации (для v1 - v1 (1 аргумент), v1.operator argument_list() (2 аргумента)) и выбирается наиболее удачная непротеворечивая
        
        std::transform(@v1, @v2, pituz); // или явное раскрытие для любителей питона
        Ответить
        • Наверное, при проектировании посчитали слишком сложным и нинужным.
          А теперь, вон, всё переводят на «ranges», потому что внезапно оказалось, что никто (кроме сумасшедших) не любит писать тонну вербозного говна для выражения элементарных действий.
          Ответить
        • Почему, почему столь несовершенно и глупо?!
          Ответить
      • >> const std::unordered_map<byte_t, std::function<byte_t(byte_t)>>
        >> [](byte_t x, byte_t y) { return mapper.at(y)(x); }
        Ахаха
        Я в js тоже так пишу когда накатывается ненависть к switch
        Ответить
      • > Пизде-е-е-е-е-е-е-ец. Ну хоть бы std::array, блядь!..

        То ли дело PHP - там массив это ordered map
        Ответить
      • > …чо, бля?

        Умножение на 2 в поле галуа, очевидно же.
        Ответить
      • > return (x < 128) ? x << 1 : (x << 1 & 0xff) ^ 0x1b;

        0x1b чем-то отличается от 0x1?
        Ответить
        • Ну да, это 43 а не 1.
          Ответить
        • Это не ассемблер, поэтому b — это не суффикс, означающий двоичное число, а шестнадцатеричная цифра, означающая одиннадцать.
          Ответить
          • бляяяяяяяя
            Ответить
            • Это ещё не «бляяяяяяяя»
              int a = 0016;     // 14
              int b = 0o16;     // 14
              
              0_o

              Причём это не только сишка, а кресты, ява, шарп и жс.
              Ответить
              • Особенно круто в языках со слабой типизацией, в которых "0016" кастуется к десятичному числу 16, а 0016 — это восьмеричное число, равное десятичному 14.
                Ответить
                • А почему во время слабого каста нельзя указать систему счисления? Вдруг я хочу написать "0х80" >> 7.
                  Ответить
                  • Number.parseInt('0016', 8) // 14

                    Бтв, твой пример отработает корректно и "0х80" будет шестнадцатеричным числом
                    Ответить
              • Нафига вообще эта дрисня восьмеричная нужна? У неё есть хоть один реальный пример использования, кроме выставления атрибутов файлов в юниксоидных ОС?

                Кстати, то ли в «C++17», то ли в «C++20» эти восьмеричные литералы убрали к херам. Именно поэтому…
                Ответить
                • backward compability

                  >Кстати, то ли в «C++17», то ли в «C++20» эти восьмеричные литералы убрали к херам

                  Хаха. То есть кресты настолько дно, что старые сишные программы в них работать уже не будут?

                  Или хуже того: 0016 станет интепретироваться правильно, как 16. И поведение программы изменится.

                  >Нафига вообще эта дрисня восьмеричная нужна?

                  Вопрос в другом.

                  Зачем это древнее говно 70х было тянуть в относительно новые языки яву, жс, шарп и пхп?

                  Царь был прав: всё воруют из сишки, даже восьмеричное хукирское говно и то своровали, сидят дрочат и обмазываются.
                  Ответить
                • > атрибутов файлов

                  Ещё инструкции PDP-11 удобно было составлять.
                  Ответить
                • t a r
                  a
                  r
                  Ответить
                • Вот это да. Тем более, когда есть однозначный и явный способ задать восьмеричного питуха (я, кстати, про него не знал). А придурошный ноль всё портит не давая красиво отформатировать десятичные числа.
                  Ответить
    • святое говно
      Ответить
    • странно, что после НГ число кур и петушков не сократилос.
      Ответить
    • Видно же, что перевод с "PHP".
      Хуле вы доебались, пидорашки?
      Ответить
    • Сосите крестобляди, будете всю жизнь с таким дерьмом возиться, учитесь код писать
      Ответить
    • Именно поэтому я за "Java Script"
      Ответить

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