Огромным недостатком языка Си (за который бы голову оторвать его создателям) является отсутствие операторов циклического битового сдвига, которые присутствуют практически на всех процессорах и без которых не обходится ни подсчет CRC32, ни вычисление корректирующих кодов Рида-Соломона, ни куча других подобных алгоритмов.
Некоторые программисты используют ассемблерные вставки, прибегая к непосредственному вызову команд процессора (на x86 это ROL/ROR – циклический битовый сдвиг влево и вправо соответственно), однако, такое решение делает программу непереносимой, причем, совершенно неоправданно непереносимой, поскольку, циклический сдвиг элементарно реализуется стандартными средствами Си.
Существует множество способов сделать это, вот только один из них. Не самый быстрый, требующий двух дополнительных переменных (хотя, в принципе, можно обойтись и одной), зато наглядный и универсальный, то есть работающий с переменными любой разрядности:
int rol(int a, int n)
{
int t1, t2;
n = n % (sizeof(a)*8); // нормализуем n
t1 = a << n; // двигаем а вправо на n бит, теряя старшие биты
t2 = a >> (sizeof(a)*8 - n); // перегоняем старшие биты в младшие
return t1 | t2; // объединяем старшие и младшие биты
}
int ror(int a, int n)
{
int t1, t2;
n = n % (sizeof(a)*8); // нормализуем n
t1 = a >> n; // двигаем а влево на n бит, теряя младшие биты
t2 = a << (sizeof(a)*8 - n); // перегоняем младшие биты в старшие
return t1 | t2; // объединяем старшие и младшие биты
}