Я думаю если провести опрос, то многие программисты ответят, что в 1С нет штатных средств для работы с отдельными битами, нет операторов XOR, OR, AND над числами.
Расчет хеша SHA-1 без использования каких-либо внешних компонет - возможно ли это в 1Cv8? Оказывается вполне возможно!
В прикрепленном файле содержится готовая обработка, которая возвращает SHA-1 хеш от указанной строки.
Для понимания как это реализовано на 1с вспомним двоичную систему счисления. В принципе, если представить целое десятичное число в двоичной системе счисления, то как раз получим последовательность бит. Например число 128 в двоичной счисления будет иметь вид 10000000 для 8-битного представления или 00000000000000000000000010000000 для 32-битного, а 129 соответственно 10000001 или 00000000000000000000000010000001.
Т.е. число в десятичной системе = ΣBi·2i, где Bi - бит из двоичного числа, а отсчет битов начинается с нуля. Т.е. для числа 10000001 получаем 128·1+64·0+32·0+16·0+8·0+4·0+2·0+1·1=129
Для обратного перевода можно пользоваться несколькими способами:
1) Для получения битов начиная со старшего, заканчивая младшим:
Исходное число, например 129, делим на 2^7, если получается больше единицы, то первый бит - 1, иначе 0. Далее Из исходного числа 129 вычитаем 2^7*бит и получаем 129-128*1=1. Далее получаем следующий бит - 1 делим на 2^6, получаем число меньшее единицы, т.е. текущий бит будет равен нулю. Теперь повторем вычитание текущего множителя 2^6 - 1-2^6*0=1. Таким образо дроходим до множителя 2^0 - 1/2^0=1 - т.е. последний бит равен 1.
Число = 129;
Битность = 8;
Биты = "";
Для й = 1 По Битность Цикл
Множитель = pow(2, Битность - й);
Бит = Цел(Число / Множитель);
Число = Число - Множитель * Бит;
Биты = Биты + Бит;
КонецЦикла;
Сообщить(Биты);
2) Для получения битов начиная с младшего до страшего:
Исходное число, например 129, делим оператором % на 2, получаем остаток от деления 1 - это крайний левый бит. Теперь делим нацело 129/2, получаем 64. Далее 64 опять делим оператором % на 2 - получаем следующий бит - 0. Продолжаем так вычислять пока не получим нужные 8 бит.
Число = 129;
Битность = 8;
Биты = "";
Для й = 1 По Битность Цикл
Бит = Число % 2;
Число = Цел(Число / 2);
Биты = Строка(Бит) + Биты;
КонецЦикла;
Сообщить(Биты);
3) В вышеописаных способах мы изменяем входное число, например 129, но можно вычислять биты не изменяя его. Например старший бит это ЦЕЛ(129/2^7)%2=1, следующий ЦЕЛ(129/2^6)%2=0 и так далее до младшего бита ЦЕЛ(129/2^0)%2=1
Число = 129;
Битность = 32;
Биты = "";
Для й = 1 По Битность Цикл
Бит = Цел(Число / pow(2, Битность - й)) % 2;
Биты = Биты + Строка(Бит);
КонецЦикла;
Сообщить(Биты);
Привожу код готовых функций XOR, LR, RR, AND, OR при помощи которых можно вычислить практически любой распространенный хэш
Функция _XOR(Знач A, Знач B, L = 8)
R = 0;
Для I = 1 по L Цикл
M = POW(2, L - I);
R = R + M * ?((A < M) = (B < M), 0, 1);
A = ?(A < M, A, A - M);
B = ?(B < M, B, B - M);
КонецЦикла;
Возврат R;
КонецФункции
Функция _LR(Знач A, S, L = 8)
Возврат Цел(A / POW(2, L - S)) + POW(2, S) * (A % POW(2, L - S));
КонецФункции
Функция _RR(Знач A, S, L = 8)
Возврат Цел(A / POW(2, S)) + POW(2, S) * (A % POW(2, S));
КонецФункции
Функция _AND(Знач A, Знач B, L = 8)
R = 0;
Для I = 1 по L Цикл
M = POW(2, L - I);
R = R + M * ?((A >= M) AND (B >= M), 1, 0);
A = ?(A < M, A, A - M);
B = ?(B < M, B, B - M);
КонецЦикла;
Возврат R;
КонецФункции
Функция _OR(Знач A, Знач B, L = 8)
R = 0;
Для I = 1 по L Цикл
M = POW(2, L - I);
R = R + M * ?((A >= M) OR(B >= M), 1, 0);
A = ?(A < M, A, A - M);
B = ?(B < M, B, B - M);
КонецЦикла;
Возврат R;
КонецФункции
Так же в обработку встроен простой замер производительности, который показывает, что циклы в одну строку показывают заметный прирост только при включенном сеансе отладки :)