Во всех упражнениях (если не оговорено иное) нельзя использовать
арифметические операторы сложения, умножения, вычитания,
деления, взятия остатка.
Вместо них используем побитовые операторы &
, |
, ~
, ^
, <<
, >>
.
Входное число A имеет тип unsigned int
(если не оговорено иное).
Номера битов всегда задаются корректно, то есть принимают значения от 0 до 31.
Дано число k, 0≤k≤31. Запишите число 2k, то есть число, у которого k-й бит равен 1, а остальные — нули.
Ввод | Вывод |
---|---|
8 |
256 |
Даны два неравных целых неотрицательных числа: k и n, не превосходящие 31. Вычислите 2k+2n.
Ввод | Вывод |
---|---|
0 1 |
3 |
Дано целое число A и целое неотрицательное число число k. Обнулите у числа A его последние k бит и выведите результат.
Ввод | Вывод |
---|---|
3 1 |
2 |
Ввод | Вывод |
---|---|
12 1 |
14 |
Ввод | Вывод |
---|---|
15 2 |
11 |
Ввод | Вывод |
---|---|
179 0 |
1 |
Ввод | Вывод |
---|---|
14 1 |
12 |
Ввод | Вывод |
---|---|
126 3 |
6 |
Программа получает на вход последовательность натуральных чисел неизвестной длины. В этой последовательности все числа встречаются ровно по два раза, кроме одного. Найдите это число.
Программа должна использовать \(O(1)\) памяти.
Ввод | Вывод |
---|---|
83 |
179 |
unsigned char
, то есть от 0 до 255.
Выведите его в битовой форме: 8 бит, старшие биты слева, младшие – справа.
Ввод | Вывод |
---|---|
179 |
10110011 |
Даны числа \(a\) и \(b\). Используя только битовые операции и операции сложения и вычитания вычислите число \(x = (36a + [\frac{b}{16}]) \bmod 32\). Выведите результат на экран.
Ввод | Вывод |
---|---|
1 2 |
4 |
2 16 |
9 |
Даны числа \(a\) и \(b\). Не используя операции *
, /
, %
вычислите их произведение.
Ввод | Вывод |
---|---|
2 3 |
6 |
Дано число, замените первую справа единицу его двоичной записи на ноль.
Разрешается использовать битовые и арифметические операции. Запрещается использовать ветвления и циклы.
Ввод | Вывод |
---|---|
1 |
0 |
6 |
4 |
Дано число, замените первый справа ноль его двоичной записи на единицу.
Разрешается использовать битовые и арифметические операции. Запрещается использовать ветвления и циклы.
Ввод | Вывод |
---|---|
0 |
1 |
5 |
7 |
Дано число, переставьте его соседние биты (то есть поменяйте местами биты с номерами 0 и 1, 2 и 3, 4 и 5 и т.д.). Разрешается использовать битовые операции. Запрещается использовать арифметические операции, ветвления, циклы.
Ввод | Вывод |
---|---|
78 |
141 |
Дано целое число А и число n. Выведите запись числа A в двоичном n-разрядном дополнительном коде.
Ограничения: 2≤n≤16, -2n-1≤A≤2n-1-1. Программа должна вывести последовательность из n нулей и единиц.
Ввод | Вывод |
---|---|
5 |
00000101 |
-5 |
11111011 |
Дана запись некоторого числа в двоичном дополнительном коде. Определите это число и выведите его.
Программа получает на вход строку из нескольких нулей и единиц длиной не меньше 2 и не больше 16. Разрядность кода определяется длиной строки.
Ввод | Вывод |
---|---|
00000101 |
5 |
11111011 |
-5 |
В операционной системе BSD используется следующий алгоритм вычисления контрольных сумм.
Контрольная сумма хранится в двубайтовой целочисленной переменной \(h\), все вычисления выполняются в двубайтовой целочисленной арифметике. С самого начала эта переменная равна 0.
Далее с каждым считанным байтом \(c\) выполняются следующие операции.
Значение \(h\) циклически сдвигается вправо (то есть последний бит становится первым, не забываем, что число \(h\) является 16-битным. К значению \(h\) прибавляется значение считанного байта (то есть ASCII-кода его).
Вот пример вычисления контрольной суммы для строки “AND“
h = 0b0000000000000000 - начальная инициализация h = 0b0000000000000000 - циклический сдвиг вправо h = 0b0000000001000001 - добавили 65 - ASCII-код A h = 0b1000000000100000 - циклический сдвиг вправо h = 0b1000000001101110 - добавили 78 - ASCII-код N h = 0b0100000000110111 - циклический сдвиг вправо h = 0b0100000001111011 - добавили 68 - ASCII-код D
Результат равен 16507.
В системе Linux можно проверить результат работы при помощи
консольной команды sum
:
$ echo -n "AND" | sum
Ввод | Вывод |
---|---|
AND |
16507 |
В алгоритме Adler-32 вычисляются две 16-битные суммы: A — сумма всех байт входных данных и B — сумма всех промежуточных значений суммы A. При этом начальное значение A инициализируется числом 1, а начальное значение B — числом 0. Все вычисления проводятся по модулю 65521 (максимальное простое, меньшее \(2^{16}\)).
Таким образом, если файл состоит из байт \(d_1\), \(d_2\), ..., \(d_n\), то \(A = 1 + d_1 + d_2 + ... + d_n \bmod 65521\), \(B = (1 + d_1) + (1 + d_1 + d_2) + ... + (1 + d_1 + ... + d_n) \bmod 65521\).
Итоговым значением контрольной суммы является одно 32-битное число, в котором в старших 16 битах записано значение B, в младших 16 битах - значение A.
Вычислите контрольную сумму Adler-32 для данной строки.
Ввод | Вывод |
---|---|
AND |
27656404 |
Алгоритм хеширования FNV-1 устроен следующим образом. Используется 64-битная арифметика. Переменная \(h\) хранит текущее значение хеш-функции. Начальное значение \(h\) равно 14695981039346656037. На каждом шаге значение \(h\) домножается на 1099511628211, затем делается побитовое исключающее ИЛИ с очередным байтом входных данных.
Вычислите значение хеш-функции FNV-1 для данной строки.
Ввод | Вывод |
---|---|
AND |
15595937027161525016 |
Алгоритм хеширования PJW-32 устроен следующим образом. Используется 32-битная арифметика. Переменная \(h\) хранит текущее значение хеш-функции. Далее для каждого считанного байта \(с\) сообщения выполняются следующие операции:
1. Значение \(h\) сдвигается на 4 бита влево, к нему прибавляется (арифметическим суммированием) значение \(c\).
2. Если хотя бы один из 4 старших битов \(h\) равен 1, то старшие 4 бита сдвигаются на 24 бита вправо, и выполняется операция побитового исключающего ИЛИ со значением \(h\). После чего обнуляются старшие 4 бита значения \(h\).
Ввод | Вывод |
---|---|
AND |
17956 |
SHA-1 — алгоритм, вычисляющий криптографические контрольные суммы от произвольной битовой последовательности. Результатом вычисления функции SHA-1 является 160-битный хэш, который как правило записывается в виде 40 16-ричных цифр. Хэш-функция является односторонней, то есть по значению хэш-функции тяжело подобрать какую-либо исходную последовательность, имеющую такое значение хэш-функции.
Изучите описание алгоритма вычисления контрольной суммы SHA-1 по материалам википедии и реализуйте данный алгоритм.
Программа получает на вход одну строку и должна вывести значение SHA-1 суммы
для этой строки. Исходная последовательность байт для вычисления SHA-1 суммы
состоит только из символов этой строки, так в примере ниже входная строка
имеет длину 3 байта = 24 бита. Добавлять к строке символ \n
и иные спецсимволы не нужно.
Программа должна вывести 40 16-ричных цифр, цифры a
-f
записываются в строчном регистре.
Ввод | Вывод |
---|---|
sha |
d8f4590320e1343a915b6394170650a8f35d6926 |
Обратите внимание, вам достаточно реализовать чуть более простой вариант SHA-1, который работает только в случае, когда исходное сообщение состоит из целого числа байт, в то время как спецификация SHA-1 описывает алгоритм, который получает на вход последовательность бит произвольной длины, не обязательно кратной 8.
Для тестирования можно использовать стандартную команду sha1sum
из дистрибутива Linux. Например, ответ на тест из условия получен при помощи
команды echo -n "sha" | sha1sum
.