Генерация хэша строки (1Cv8)
Содержание
Некоторые реализации:
Хэш строки
Функция стрПолучитьХэш(Знач стрСтрока) Экспорт
Сумма1 = 0;
Сумма2 = 1;
ДлинаСтроки = СтрДлина(стрСтрока);
Для ъ = 1 По ДлинаСтроки Цикл
//КодСимвола = КодСимвола(стрСтрока, ДлинаСтроки);
КодСимвола = КодСимвола(Сред(стрСтрока, ДлинаСтроки, 1));
Сумма1 = Сумма1+КодСимвола*ДлинаСтроки;
Сумма2 = Сумма2*КодСимвола;
ДлинаСтроки = ДлинаСтроки-1;
КонецЦикла;
ПростоеЧисло = 165684646484683;
Если Сумма1 = 0 Тогда Сумма1 = ПростоеЧисло; КонецЕсли;
КодСимвола = Сумма1*Сумма2*ПростоеЧисло;
Возврат Лев(Формат(КодСимвола,"ЧГ = "), 32);
КонецФункции
Хэш md5
Источник: http://1c.proclub.ru/modules/mydownloads/personal.php?cid=5&lid=5287
// Обработка рассчитывает Хэш код текста по алгоритму MD5
// Весь алгоритм реализован на языке 1С и не требует никаких дополнительных внешних компонент.
// Можно вводить текст интерактивно или передавать из другой обработки
//
// При запуске из другой обработки передается СписокЗначений с параметрами:
// "Строка"-собственно строка текста или объект типа "Текст"
// Возврат "ХэшКод"-собственно 32 символа Хэш кода
//
// Текст можно передавать поблочно
// При передаче текста по блокам
// ДЛИНА БЛОКА, КРОМЕ ПОСЛЕДНЕГО, ДОЛЖНА БЫТЬ КРАТНА 64 БАЙТАМ!
// дополнительно задаются
// "Длина" - равна -1(минус 1) для всех блоков кроме последнего
// для последнего блока длина всего текста в байтах
// "ХэшКод" - Хэш код предыдущего блока (для первого блока не задается)
//
Перем A,B,C,D; // Составляющие ХэшКода (по 4 байта или 8 символов в 16с/с)
Перем A_[32],B_[32],C_[32],D_[32];
Перем EAX[32],EBX[32],ECX[32],EDX[32]; // Регистры
Перем S11,S12,S13,S14,S21,S22,S23,S24,S31,S32,S33,S34,S41,S42,S43,S44;
Перем M[64];
Перем Степень[32];
Перем Stepen31; //2 в степени 31
Перем Stepen32; //2 в степени 32
Перем X[16]; //Текстовый массив в числовом коде
//Перем Степень[32]; // Массив степеней
Процедура Расчет(Стр,Длина=0) Далее
//*******************************************
Процедура _XOR(П1[],П2[],Итог[])
Для инд=1 По 32 Цикл
Если П1[инд] <> П2[инд] Тогда
Итог[инд]=1;
Иначе
Итог[инд]=0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура _AND(П1[],П2[],Итог[])
Для инд=1 По 32 Цикл
Если (П1[инд]=1) И (П2[инд]=1) Тогда
Итог[инд]=1;
Иначе
Итог[инд]=0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура _OR(П1[],П2[],Итог[])
Для инд=1 По 32 Цикл
Если (П1[инд]=1) ИЛИ (П2[инд]=1) Тогда
Итог[инд]=1;
Иначе
Итог[инд]=0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура _ADD(П1[],П2[],Итог[])
Добавка=0;
Для инд=1 По 32 Цикл
Итог[инд]=П1[инд]+П2[инд]+Добавка;
Если Итог[инд]=2 Тогда
Итог[инд]=0;
Добавка=1;
ИначеЕсли Итог[инд]=3 Тогда
Итог[инд]=1;
Добавка=1;
Иначе
Добавка=0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура _NOT(П1[],Итог[])
Для инд=1 По 32 Цикл
Если П1[инд]=0 Тогда
Итог[инд]=1;
Иначе
Итог[инд]=0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура _ROL(П1[],П2,Итог[])
Для инд=1 По 32 Цикл
инд1=инд+П2;
Если инд1 > 32 Тогда
инд1=инд1-32;
КонецЕсли;
Итог[инд1]=П1[инд];
КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура FF(a[],b[],c[],d[],X,s,t)
_and(b,c,EAX);
_not(b,EBX);
_and(EBX,d,ECX);
_or(EAX,ECX,EBX);
X1=X+t;
Если X1 >= Stepen32 Тогда
X1=X1-Stepen32;
КонецЕсли;
Для инд=1 По 32 Цикл
инд1=32-инд+1;
Степ=Степень[инд1];
Если X1 >= Степ Тогда
X1=X1-Степ;
EDX[инд1]=1;
Иначе
EDX[инд1]=0;
КонецЕсли;
КонецЦикла;
_ADD(EBX,a,ECX);
_ADD(ECX,EDX,EAX);
_rol(EAX,s,ECX);
_ADD(ECX,b,a);
КонецПроцедуры
//*******************************************
Процедура GG(a[],b[],c[],d[],X,s,t)
_and(b,d,EAX);
_not(d,EDX);
_and(EDX,c,ECX);
_or(EAX,ECX,EBX);
X1=X+t;
Если X1 >= Stepen32 Тогда
X1=X1-Stepen32;
КонецЕсли;
Для инд=1 По 32 Цикл
инд1=32-инд+1;
Степ=Степень[инд1];
Если X1 >= Степ Тогда
X1=X1-Степ;
EDX[инд1]=1;
Иначе
EDX[инд1]=0;
КонецЕсли;
КонецЦикла;
_ADD(EBX,a,ECX);
_ADD(ECX,EDX,EAX);
_rol(EAX,s,ECX);
_ADD(ECX,b,a);
КонецПроцедуры
//*******************************************
Процедура HH(a[],b[],c[],d[],X,s,t)
_xor(b,c,EAX);
_xor(EAX,d,EBX);
X1=X+t;
Если X1 >= Stepen32 Тогда
X1=X1-Stepen32;
КонецЕсли;
Для инд=1 По 32 Цикл
инд1=32-инд+1;
Степ=Степень[инд1];
Если X1 >= Степ Тогда
X1=X1-Степ;
EDX[инд1]=1;
Иначе
EDX[инд1]=0;
КонецЕсли;
КонецЦикла;
_ADD(EBX,a,ECX);
_ADD(ECX,EDX,EAX);
_rol(EAX,s,ECX);
_ADD(ECX,b,a);
КонецПроцедуры
//*******************************************
Процедура II(a[],b[],c[],d[],X,s,t)
_not(d,EAX);
_or(EAX,b,ECX);
_xor(ECX,c,EBX);
X1=X+t;
Если X1 >= Stepen32 Тогда
X1=X1-Stepen32;
КонецЕсли;
Для инд=1 По 32 Цикл
инд1=32-инд+1;
Степ=Степень[инд1];
Если X1 >= Степ Тогда
X1=X1-Степ;
EDX[инд1]=1;
Иначе
EDX[инд1]=0;
КонецЕсли;
КонецЦикла;
_ADD(EBX,a,ECX);
_ADD(ECX,EDX,EAX);
_rol(EAX,s,ECX);
_ADD(ECX,b,a);
КонецПроцедуры
//******************************************************************************
Функция Из_16_В_Число(Знач Значение)
Результат=0;
Значение=ВРег(Значение);
М=1;
Для Х=1 По 4 Цикл
Результат=Результат+(Найти("0123456789ABCDEF",Сред(Значение,2*Х,1))-1)*М;
М=М*16;
Результат=Результат+(Найти("0123456789ABCDEF",Сред(Значение,2*Х-1,1))-1)*М;
М=М*16;
КонецЦикла;
Возврат Результат;
КонецФункции
//*******************************************
Функция Из_Число_В_16(Знач Значение)
Результат="";
Для инд=1 По 4 Цикл
Остат=Значение%16+1;
Результат1=Сред("0123456789ABCDEF",Остат,1);
Значение=Цел(Значение/16);
Остат=Значение%16+1;
Результат2=Сред("0123456789ABCDEF",Остат,1);
Значение=Цел(Значение/16);
Результат=Результат+Результат2+Результат1;
КонецЦикла;
Возврат Результат;
КонецФункции
//*******************************************
Процедура MD5Hash()
Перем A1[32],B1[32],C1[32],D1[32];
Для i=1 По 32 Цикл
A1[i] = A_[i];
B1[i] = B_[i];
C1[i] = C_[i];
D1[i] = D_[i];
КонецЦикла;
// --------------------------------------------------------------------------
// Round 1.
// --------------------------------------------------------------------------
FF (a_,b_,c_,d_, X[1], S11, 3614090360) ;// Step 1
FF (d_,a_,b_,c_, X[2], S12, 3905402710) ;// Step 2
FF (c_,d_,a_,b_, X[3], S13, 606105819) ;// Step 3
FF (b_,c_,d_,a_, X[4], S14, 3250441966) ;// Step 4
FF (a_,b_,c_,d_, X[5], S11, 4118548399) ;// Step 5
FF (d_,a_,b_,c_, X[6], S12, 1200080426) ;// Step 6
FF (c_,d_,a_,b_, X[7], S13, 2821735955) ;// Step 7
FF (b_,c_,d_,a_, X[8], S14, 4249261313) ;// Step 8
FF (a_,b_,c_,d_, X[9], S11, 1770035416) ;// Step 9
FF (d_,a_,b_,c_, X[10],S12, 2336552879) ;// Step 10
FF (c_,d_,a_,b_, X[11],S13, 4294925233) ;// Step 11
FF (b_,c_,d_,a_, X[12],S14, 2304563134) ;// Step 12
FF (a_,b_,c_,d_, X[13],S11, 1804603682) ;// Step 13
FF (d_,a_,b_,c_, X[14],S12, 4254626195) ;// Step 14
FF (c_,d_,a_,b_, X[15],S13, 2792965006) ;// Step 15
FF (b_,c_,d_,a_, X[16],S14, 1236535329) ;// Step 16
// --------------------------------------------------------------------------
// Round 2.
// --------------------------------------------------------------------------
GG (a_,b_,c_,d_, X[2], S21, 4129170786) ;// Step 17
GG (d_,a_,b_,c_, X[7], S22, 3225465664) ;// Step 18
GG (c_,d_,a_,b_, X[12],S23, 643717713) ;// Step 19
GG (b_,c_,d_,a_, X[1], S24, 3921069994) ;// Step 20
GG (a_,b_,c_,d_, X[6], S21, 3593408605) ;// Step 21
GG (d_,a_,b_,c_, X[11],S22, 38016083) ;// Step 22
GG (c_,d_,a_,b_, X[16],S23, 3634488961) ;// Step 23
GG (b_,c_,d_,a_, X[5], S24, 3889429448) ;// Step 24
GG (a_,b_,c_,d_, X[10],S21, 568446438) ;// Step 25
GG (d_,a_,b_,c_, X[15],S22, 3275163606) ;// Step 26
GG (c_,d_,a_,b_, X[4], S23, 4107603335) ;// Step 27
GG (b_,c_,d_,a_, X[9], S24, 1163531501) ;// Step 28
GG (a_,b_,c_,d_, X[14],S21, 2850285829) ;// Step 29
GG (d_,a_,b_,c_, X[3], S22, 4243563512) ;// Step 30
GG (c_,d_,a_,b_, X[8], S23, 1735328473) ;// Step 31
GG (b_,c_,d_,a_, X[13],S24, 2368359562) ;// Step 32
// --------------------------------------------------------------------------
// Round 3.
// --------------------------------------------------------------------------
HH (a_,b_,c_,d_, X[6], S31, 4294588738) ;// Step 33
HH (d_,a_,b_,c_, X[9], S32, 2272392833) ;// Step 34
HH (c_,d_,a_,b_, X[12],S33, 1839030562) ;// Step 35
HH (b_,c_,d_,a_, X[15],S34, 4259657740) ;// Step 36
HH (a_,b_,c_,d_, X[2], S31, 2763975236) ;// Step 37
HH (d_,a_,b_,c_, X[5], S32, 1272893353) ;// Step 38
HH (c_,d_,a_,b_, X[8], S33, 4139469664) ;// Step 39
HH (b_,c_,d_,a_, X[11],S34, 3200236656) ;// Step 40
HH (a_,b_,c_,d_, X[14],S31, 681279174) ;// Step 41
HH (d_,a_,b_,c_, X[1], S32, 3936430074) ;// Step 42
HH (c_,d_,a_,b_, X[4], S33, 3572445317) ;// Step 43
HH (b_,c_,d_,a_, X[7], S34, 76029189) ;// Step 44
HH (a_,b_,c_,d_, X[10],S31, 3654602809) ;// Step 45
HH (d_,a_,b_,c_, X[13],S32, 3873151461) ;// Step 46
HH (c_,d_,a_,b_, X[16],S33, 530742520) ;// Step 47
HH (b_,c_,d_,a_, X[3], S34, 3299628645) ;// Step 48
// --------------------------------------------------------------------------
// Round 4.
// --------------------------------------------------------------------------
II (a_,b_,c_,d_, X[1], S41, 4096336452) ;// Step 49
II (d_,a_,b_,c_, X[8], S42, 1126891415) ;// Step 50
II (c_,d_,a_,b_, X[15],S43, 2878612391) ;// Step 51
II (b_,c_,d_,a_, X[6], S44, 4237533241) ;// Step 52
II (a_,b_,c_,d_, X[13],S41, 1700485571) ;// Step 53
II (d_,a_,b_,c_, X[4], S42, 2399980690) ;// Step 54
II (c_,d_,a_,b_, X[11],S43, 4293915773) ;// Step 55
II (b_,c_,d_,a_, X[2], S44, 2240044497) ;// Step 56
II (a_,b_,c_,d_, X[9], S41, 1873313359) ;// Step 57
II (d_,a_,b_,c_, X[16],S42, 4264355552) ;// Step 58
II (c_,d_,a_,b_, X[7], S43, 2734768916) ;// Step 59
II (b_,c_,d_,a_, X[14],S44, 1309151649) ;// Step 60
II (a_,b_,c_,d_, X[5], S41, 4149444226) ;// Step 61
II (d_,a_,b_,c_, X[12],S42, 3174756917) ;// Step 62
II (c_,d_,a_,b_, X[3], S43, 718787259) ;// Step 63
II (b_,c_,d_,a_, X[10],S44, 3951481745) ;// Step 64
// --------------------------------------------------------------------------
_ADD(A_,A1,A_);
_ADD(B_,B1,B_);
_ADD(C_,C1,C_);
_ADD(D_,D1,D_);
КонецПроцедуры
//*******************************************
Процедура ПриОткрытии()
Если ТипЗначенияСтр(Форма.Параметр)="СписокЗначений" Тогда
СтатусВозврата(0);
Стр=Форма.Параметр.Получить("Строка");
Если ПустоеЗначение(Форма.Параметр.Получить("ХэшКод")) <> 1 Тогда
Код=Форма.Параметр.Получить("ХэшКод");
A = Из_16_В_Число(Лев(Код,8));
B = Из_16_В_Число(Сред(Код,9,8));
C = Из_16_В_Число(Сред(Код,17,8));
D = Из_16_В_Число(Прав(Код,8));
Иначе
A = 1732584193;
B = 4023233417;
C = 2562383102;
D = 271733878;
КонецЕсли;
Длина=Число(Форма.Параметр.Получить("Длина"));
Для i=1 По 32 Цикл
i1=32-i+1;
Степ=Степень[i1];
Если A >= Степ Тогда
A=A-Степ;
A_[i1]=1;
Иначе
A_[i1]=0;
КонецЕсли;
Если B >= Степ Тогда
B=B-Степ;
B_[i1]=1;
Иначе
B_[i1]=0;
КонецЕсли;
Если C >= Степ Тогда
C=C-Степ;
C_[i1]=1;
Иначе
C_[i1]=0;
КонецЕсли;
Если D >= Степ Тогда
D=D-Степ;
D_[i1]=1;
Иначе
D_[i1]=0;
КонецЕсли;
КонецЦикла;
Если ТипЗначенияСтр(Стр)="Текст" Тогда
Текст=Стр;
Стр="";
Длина=0;
Для инд=1 По Текст.КоличествоСтрок() Цикл
Стр1=Текст.ПолучитьСтроку(инд);
Стр=Стр+Стр1;
Пока СтрДлина(Стр) >= 8192 Цикл
Расчет(Лев(Стр,8192),-1);
Длина=Длина+8192;
Стр=Сред(Стр,8193);
КонецЦикла;
КонецЦикла;
Длина=Длина+СтрДлина(Стр);
КонецЕсли;
Расчет(Стр,Длина);
A = 0;
B = 0;
C = 0;
D = 0;
Для i=1 По 32 Цикл
Степ=Степень[i];
Если A_[i]=1 Тогда
A=A+Степ;
КонецЕсли;
Если B_[i]=1 Тогда
B=B+Степ;
КонецЕсли;
Если C_[i]=1 Тогда
C=C+Степ;
КонецЕсли;
Если D_[i]=1 Тогда
D=D+Степ;
КонецЕсли;
КонецЦикла;
ХэшКод=Из_Число_В_16(A)+Из_Число_В_16(B)+Из_Число_В_16(C)+Из_Число_В_16(D);
Форма.Параметр.Установить("ХэшКод",ХэшКод);
Возврат;
КонецЕсли;
КонецПроцедуры
//*******************************************
Процедура Расчет(Стр,Длина=0)
Перем Мас[64];
Если Длина=0 Тогда
Длина=СтрДлина(Стр);
КонецЕсли;
// Определение Хэш кодов 64 байтных блоков
ДлСтр=СтрДлина(Стр);
Пока ДлСтр >= 64 Цикл
i1=0;
Для i = 1 По 16 Цикл
X[i]=КодСимв(Сред(Стр,i1+1,1))+
КодСимв(Сред(Стр,i1+2,1))*256+
КодСимв(Сред(Стр,i1+3,1))*65536+
КодСимв(Сред(Стр,i1+4,1))*16777216;
i1=i1+4;
КонецЦикла;
MD5Hash();
Стр=Сред(Стр,65);
ДлСтр=СтрДлина(Стр);
КонецЦикла;
// Финал - определение Хэш кода последнего блока
Если Длина <> -1 Тогда // Если Длина=-1 то значит это не последний блок
ДлинаБит=Длина*8;
Для i = 1 По ДлСтр Цикл
Мас[i]=КодСимв(Сред(Стр,i,1));
КонецЦикла;
Мас[ДлСтр+1]=128;
Длина=ДлСтр+1;
// В последнем блоке нет свободных 8 байт для длины
// Дополняем блок до 64 байт
Если Длина > 56 Тогда
Для i = Длина+1 По 64 Цикл
Мас[i]=0;
КонецЦикла;
i1=0;
Для i = 1 По 16 Цикл
X[i]=Мас[i1+1]+
Мас[i1+2]*256+
Мас[i1+3]*65536+
Мас[i1+4]*16777216;
i1=i1+4;
КонецЦикла;
MD5Hash();
Длина=0;
КонецЕсли;
// Дополняем блок до 56 байт и заносим длину в битах
Для i = Длина+1 По 56 Цикл
Мас[i]=0;
КонецЦикла;
i1=0;
Для i = 1 По 14 Цикл
X[i]=Мас[i1+1]+
Мас[i1+2]*256+
Мас[i1+3]*65536+
Мас[i1+4]*16777216;
i1=i1+4;
КонецЦикла;
X[15]=ДлинаБит%Stepen32;
X[16]=Цел(ДлинаБит/Stepen32);
MD5Hash();
КонецЕсли;
КонецПроцедуры
//*******************************************
Процедура Сформировать()
A = 1732584193;
B = 4023233417;
C = 2562383102;
D = 271733878;
Для i=1 По 32 Цикл
i1=32-i+1;
Степ=Степень[i1];
Если A >= Степ Тогда
A=A-Степ;
A_[i1]=1;
Иначе
A_[i1]=0;
КонецЕсли;
Если B >= Степ Тогда
B=B-Степ;
B_[i1]=1;
Иначе
B_[i1]=0;
КонецЕсли;
Если C >= Степ Тогда
C=C-Степ;
C_[i1]=1;
Иначе
C_[i1]=0;
КонецЕсли;
Если D >= Степ Тогда
D=D-Степ;
D_[i1]=1;
Иначе
D_[i1]=0;
КонецЕсли;
КонецЦикла;
Расчет(СтрокаХэш);
A = 0;
B = 0;
C = 0;
D = 0;
Для i=1 По 32 Цикл
Степ=Степень[i];
Если A_[i]=1 Тогда
A=A+Степ;
КонецЕсли;
Если B_[i]=1 Тогда
B=B+Степ;
КонецЕсли;
Если C_[i]=1 Тогда
C=C+Степ;
КонецЕсли;
Если D_[i]=1 Тогда
D=D+Степ;
КонецЕсли;
КонецЦикла;
ХэшКод=Из_Число_В_16(A)+Из_Число_В_16(B)+Из_Число_В_16(C)+Из_Число_В_16(D);
Форма.ХэшКод.Заголовок(ХэшКод);
КонецПроцедуры
//*******************************************
S11 = 7;
S12 = 12;
S13 = 17;
S14 = 22;
S21 = 5;
S22 = 9;
S23 = 14;
S24 = 20;
S31 = 4;
S32 = 11;
S33 = 16;
S34 = 23;
S41 = 6;
S42 = 10;
S43 = 15;
S44 = 21;
Степень[1]=1;
Для инд=2 По 32 Цикл
Степень[инд]=Степень[инд-1]*2;
КонецЦикла;
Stepen31=Степень[32];
Stepen32=Stepen31*2;
Хэш через объект capicom
- http://www.infostart.ru/projects/2964/
- Описание capicom: http://msdn.microsoft.com/en-us/library/aa380255(VS.85).aspx
objHashedData = Новый COMОбъект("CAPICOM.HashedData");
objHashedData.Algorithm = 3;
objHashedData.Hash(НужнаяСтрока);
Сообщить(objHashedData.Value);