Имя: Пароль:
1C
1С v8
Нужно MD5 и SHA1
,
0 mvgfirst
 
04.04.13
13:27
Для работы с вебсервисом банка необходимо все XML-ки "шифровать" используя оба алгоритма (так-то там все замороченее еще и base64 используется - но с ним вроде бы ясно все)

С банком работать предполагается через Регаламентные задания, которые "крутятся" на x64 сервере.

Подскажие как получить Хеши и MD5 и SHA1 на сервере 1С предприятия.

Я нашел компоненту StringsNative - она это умеет, но к сожалению только для x86. На севрере x64 - она не подключатеся.

Кто как решал такую задачу? Уверен я не первый кто столкнулся с проблемой.
1 alexei366
 
04.04.13
13:28
Хеши и MD5 и SHA1 файлов? или чего поконкретней опиши
2 mvgfirst
 
04.04.13
13:33
Я работаю с вебсервисом банка, подписываю кредитные договора
Для подписания необходимо что бы POST запросом отправлялся XML файл (определенной структуры как надо банку) который должен быть закодирован через base64, а потом из результирующего файла получаем хеш SHA1 потом конкатенируем результаты и 1000 раз вычисляем хеш MD5 - и уже после этого сам файл и полученный хеш отправляем в банк

Короче - не я это придумал - но альтернативы нет ))))
И пока тестил на клиенте - все работало - положил в регламетное задание - перестала загружаться компонента.

Автора попросил - что бы он скомпилил x64 но уверенности что он это сделает нет никакой - поэтому ищу альтернативные способы решения
3 drcrasher
 
04.04.13
13:37
(0) wiki:OpenSSL тебе в помощь
4 mvgfirst
 
04.04.13
13:38
(3) И каким образом это мне поможет?!
5 drcrasher
 
04.04.13
13:42
(4) в статью на вики ходил?
надпись "есть для винды" видел?

скачать/поставить на сервер/потестить пробовал?
почитать про wsh и написать скрипт не?

хотя такая задачка одним чудикам обошлась в 5Круб. ;)
6 РыжийОвощ
 
04.04.13
13:45
(0) кури capicom.dll
7 fisher
 
04.04.13
13:46
(5) А оно под винду COM-объекты даёт?
8 alexei366
 
04.04.13
13:46
корочь гугли Новый COMОбъект("CAPICOM.HashedData");, на серваке должна быть зарегана бибиотека CAPICOM.dll, тама вроде найдёшь и sha1 и md5. А md5 кстати в 1С вычислить можно, я так сам делаю, там пишешь Новый Хеш...(точно не помню), а далее по СП
9 РыжийОвощ
 
04.04.13
13:49
(8) а это разве не возможность 8.3?
10 alexei366
 
04.04.13
13:50
(9) про md5 да, у меня 8.3.2
11 mvgfirst
 
04.04.13
13:50
А Native?
Не то что бы я придираюь - но как-то не люблю я COM-объекты, особенно если хи регистрировать надо.

Ясень пень что "на безбабий и рыбу раком" - но вдруг.... )))
12 alexei366
 
04.04.13
13:51
(11) CAPICOM вроде в каждой винде есть по умолчанию
13 vde69
 
04.04.13
14:01
(12) CAPICOM на 64х сервере не работает (по крайне мере у меня не вышло ее запустить)
14 khajit
 
04.04.13
14:04
(0) для MD5 делал внешнюю native компоненту по 64х сервер, другие варианты показались либо тормозными либо сложнореализуемыми
15 mvgfirst
 
04.04.13
14:05
(14) А поделится с общественностью? возможно?
16 khajit
 
04.04.13
14:07
(15) скинь контакты
17 alexei366
 
04.04.13
14:11
(13) фигня какаято, я тут по работе сталкиваюсь с программами которые используют данную библиотеку, так и на 32 и на 64 всё норм работает.
18 Лефмихалыч
 
04.04.13
14:27
(0) http://pajhome.org.uk/crypt/md5/scripts.html
там есть все, что надо, включая wsc, который можно зарегить, как ActiveX-объект и использовать через Новый COMОбъект()
19 mvgfirst
 
04.04.13
17:16
(16) Куда скинуть?
20 sapphire
 
04.04.13
17:18
(0) Используй бетку 8.3 - она это умеет :)
21 mvgfirst
 
04.04.13
17:26
Не уверен что это разумно, у меня рабочая база, и переводить ее на 8.3 боязно как-то
опять же лицензия (то да сё)
22 ptiz
 
04.04.13
17:30
в БСП есть функция
ВычислитьХешСтрокиПоАлгоритмуMD5
23 Ёпрст
 
04.04.13
17:36
24 Ёпрст
 
04.04.13
17:38
Функция MD5(КодируемаяСтрока)
   Хеш="";
   Попытка
       //http://pajhome.org.uk/crypt/md5/index.html

       ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl");
       ScrptCtrl.Language = "JScript";
       ScrptCtrl.AddCode("
       |var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */


      |var b64pad  = """"; /* base-64 pad character. ""="" for strict RFC compliance   */

       |var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
       |function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
       |function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
       |function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
       |function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
       |function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
       |function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
       |function md5_vm_test()
       |{
       |  return hex_md5(""abc"") == ""900150983cd24fb0d6963f7d28e17f72"";
       |}
       |function core_md5(x, len)
       |{
       |  x[len >> 5] |= 0x80 << ((len) % 32);
       |  x[(((len + 64) >>> 9) << 4) + 14] = len;
       |
       |  var a =  1732584193;
       |  var b = -271733879;
       |  var c = -1732584194;
       |  var d =  271733878;
       |
       |  for(var i = 0; i < x.length; i += 16)
       |  {
       |    var olda = a;
       |    var oldb = b;
       |    var oldc = c;
       |    var oldd = d;
       |
       |    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
       |    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
       |    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
       |    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
       |    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
       |    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
       |    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
       |    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
       |    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
       |    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
       |    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
       |    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
       |    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
       |    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
       |    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
       |    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
       |
       |    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
       |    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
       |    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
       |    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
       |    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
       |    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
       |    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
       |    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
       |    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
       |    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
       |    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
       |    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
       |    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
       |    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
       |    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
       |    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
       |
       |    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
       |    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
       |    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
       |    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
       |    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
       |    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
       |    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
       |    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
       |    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
       |    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
       |    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
       |    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
       |    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
       |    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
       |    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
       |    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
       |
       |    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
       |    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
       |    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
       |    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
       |    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
       |    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
       |    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
       |    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
       |    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
       |    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
       |    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
       |    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
       |    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
       |    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
       |    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
       |    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
       |
       |    a = safe_add(a, olda);
       |    b = safe_add(b, oldb);
       |    c = safe_add(c, oldc);
       |    d = safe_add(d, oldd);
       |  }
       |  return Array(a, b, c, d);
       |
       |}
       |
       |function md5_cmn(q, a, b, x, s, t)
       |{
       |  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
       |}
       |function md5_ff(a, b, c, d, x, s, t)
       |{
       |  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
       |}
       |function md5_gg(a, b, c, d, x, s, t)
       |{
       |  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
       |}
       |function md5_hh(a, b, c, d, x, s, t)
       |{
       |  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
       |}
       |function md5_ii(a, b, c, d, x, s, t)
       |{
       |  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
       |}
       |
       |function core_hmac_md5(key, data)
       |{
       |  var bkey = str2binl(key);
       |  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
       |
       |  var ipad = Array(16), opad = Array(16);
       |  for(var i = 0; i < 16; i++)
       |  {
       |    ipad[i] = bkey[i] ^ 0x36363636;
       |    opad[i] = bkey[i] ^ 0x5C5C5C5C;
       |  }
       |
       |  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
       |  return core_md5(opad.concat(hash), 512 + 128);
       |}
       |
       |function safe_add(x, y)
       |{
       |  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
       |  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
       |  return (msw << 16) | (lsw & 0xFFFF);
       |}
       |
       |/*
       | * Bitwise rotate a 32-bit number to the left.
       | */
       |function bit_rol(num, cnt)
       |{
       |  return (num << cnt) | (num >>> (32 - cnt));
       |}
       |
       |/*
       | * Convert a string to an array of little-endian words
       | * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
       | */
       |function str2binl(str)
       |{
       |  var bin = Array();
       |  var mask = (1 << chrsz) - 1;
       |  for(var i = 0; i < str.length * chrsz; i += chrsz)
       |    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
       |  return bin;
       |}
       |
       |function binl2str(bin)
       |{
       |  var str = """";
       |  var mask = (1 << chrsz) - 1;
       |  for(var i = 0; i < bin.length * 32; i += chrsz)
       |    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
       |  return str;
       |}
       |
       |function binl2hex(binarray)
       |{
       |  var hex_tab = hexcase ? ""0123456789ABCDEF"" : ""0123456789abcdef"";
       |  var str = """";
       |  for(var i = 0; i < binarray.length * 4; i++)
       |  {
       |    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
       |           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
       |  }
       |  return str;
       |}
       |
       |function binl2b64(binarray)
       |{
       |  var tab = ""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"";
       |  var str = """";
       |  for(var i = 0; i < binarray.length * 4; i += 3)
       |  {
       |    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
       |                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
       |                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
       |    for(var j = 0; j < 4; j++)
       |    {
       |      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
       |      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
       |    }
       |  }
       |  return str;
       |}
       |");
       
       Хэш = ScrptCtrl.Run("hex_md5", КодируемаяСтрока);
   Исключение
       Сообщить(ОписаниеОшибки(), );
   КонецПопытки;
   ScrptCtrl = "";
   Возврат Хэш;
КонецФункции // MD5()
25 mrWatson
 
04.04.13
17:50
(24) а MD5 в строку могёшь?
26 mvgfirst
 
04.04.13
17:54
(24) Я нечто подобное использовал, нашел в Интернетах в виде обработки, без использования скриптов

Но я не нашел SHA1
27 mvgfirst
 
04.04.13
17:56
(23) Про эту компоненту я писал в (0) - она незаработала в х64 сервере
28 mvgfirst
 
04.04.13
17:57
Кстати в комментах к ней (поуказанной ссылке)я же и отписался об этом.
29 Serginio1
 
04.04.13
19:00
30 Steelvan
 
04.04.13
22:37
31 Torquader
 
05.04.13
01:12
Я писал md5 на VbScript, причём используя только умножение и деление вместо сдвиговых операций.
В принципе, можно и на языке 1С это всё написать.
Просто берётся код алгоритма на Си и пишется транслятор, который честно отрабатывает указанные в коде действия через доступные операции - получается рабочий код на заданном языке программирования.
P.S. md5 на VbScript здесь уже выкладывал.
32 mvgfirst
 
06.04.13
19:39
MD5 на языке 1С - у меня уже и так есть
Мне бы еще хотя-бы sha1 получить
и я бы обошелся вообще без внешней компоненты.

К сожалению из меня весьма посредственный транслятор с других языков, да и сам принцип работы этих алгоритмов я незнаю (не нужны они не были 12 лет, и думаю сейчас единичный случай)

А времени эксперементировать с вышеуказанными ссылками особо не наблюдается, вот поэтому и ищу готовые варианты. Поэтому и опираюсь в основном на готовую внешнюю компоненту (StringsNative) - потому что в ней уже все есть и готово к употреблению.
33 Лефмихалыч
 
06.04.13
20:09
(24) [:||||||||||||:] см (18)
34 mvgfirst
 
06.04.13
23:08
Обнаружил еще один интересный факт связанный с быстродействием.

Мне по требованиям банка MD5 нужно рассчитать 1000 раз
Я, нашел обработки которые считают и SHA1 и MD5 на языке 1С без использования чего либо стороннего вообще.

Оказалось:
1. Все что я нашел некорректным образом работает с данными на русском языке
2. Работает все это ацки-медленно!!!!

Проверял используя внешнюю компоненту StringsNative (ссылка на ветку инфостарта про нее выше в топике)

Даже 10 раз считает очень медленно (2 секунды)
Внешняя компонента считает меньше чем секунда даже 1000 раз
35 Torquader
 
07.04.13
01:08
(34) Я писал Md5 на VbScript - работает всё равно очень медленно, но на файлах даёт правильный результат.
Что касается 1С версии 8, то тут как и в JavaScript - все символы двухбайтовые, то есть мы не можем разложить строку на байты, так как она двухбайтовая (значение КодСимвола не даёт нам байт).
В результате мы получаем расчёт неизвестно чего, так как нам нужно или считать строку двухбайтовой (а тогда мы не совпадём с другими алгоритмами) или переводить строку в однобайтовую, чтобы можно было её разложить на последовательность байтов.
36 mvgfirst
 
07.04.13
15:23
(35) Приблизительно понял о чем Вы говорите.
правильно ли я сделал вывод - что для того что бы корректно посчитать хеш MD5 нужно сохранить строку в файл, а уже его потом как Двоичные данные прогнать через функцию расчета хеша?
37 mvgfirst
 
07.04.13
15:27
(18) (24) (33) Используя скрпиты, у меня получилось приблизится к скорости расчета хешей такой же как и у Внешней компоненты. И хотя в моем конкретном случая я буду использовать только 1С сервер на платформе Windows - мне кажется что нужно искать способ кросс-платформенный.
И хотя сами скрипты написаны на джаве (которая вроде бы кросс-платформенная) - способ их вызоыва через MSScriptControl - не совсем кросплатформенное решение

З.Ы. Я понимаю что 8.3 - это выход из ситуации и никто уже не будет изобретать ничего нового - но ведь многие до сих пор используют 7.7 а уж сколько останется на 8.2 и не перейдут на 8.3 - предсказать еще труднее
38 Torquader
 
07.04.13
18:25
(37) SHA1 вообще простой - я его в VbScript переписал, используя только арифметические операции, но для суммирования нужно целочисленное деление и остаток от деления, которые в 1С не очень быстрые операции.
Что касается кодов символов, то по стандарту считается, что кодировка должна быть UTF-8, и Unicode из 1С в неё прекрасно переводится несколькими операциями.
39 Torquader
 
07.04.13
18:36
В восьмёрке даже массив превратили в чёрт знает что - если рассматривать число как слово в 32 бита, то доступ к каждому биту - получение свойства объекта - медленнее не представить.
Конечно, можно все 32-шага по разобрать.
40 Torquader
 
07.04.13
18:39
Короче - вот оно в VbScript:
Sub Sha1_InitConst(ByRef A(),ByRef B(),ByRef C(),ByRef D(),ByRef E(),ByRef K1(),ByRef K2(),ByRef K3,ByRef K4)
   A(31)=0
   A(30)=1
   A(29)=1
   A(28)=0
   A(27)=0
   A(26)=1
   A(25)=1
   A(24)=1
   A(23)=0
   A(22)=1
   A(21)=0
   A(20)=0
   A(19)=0
   A(18)=1
   A(17)=0
   A(16)=1
   A(15)=0
   A(14)=0
   A(13)=1
   A(12)=0
   A(11)=0
   A(10)=0
   A(9)=1
   A(8)=1
   A(7)=0
   A(6)=0
   A(5)=0
   A(4)=0
   A(3)=0
   A(2)=0
   A(1)=0
   A(0)=1
   B(31)=1
   B(30)=1
   B(29)=1
   B(28)=0
   B(27)=1
   B(26)=1
   B(25)=1
   B(24)=1
   B(23)=1
   B(22)=1
   B(21)=0
   B(20)=0
   B(19)=1
   B(18)=1
   B(17)=0
   B(16)=1
   B(15)=1
   B(14)=0
   B(13)=1
   B(12)=0
   B(11)=1
   B(10)=0
   B(9)=1
   B(8)=1
   B(7)=1
   B(6)=0
   B(5)=0
   B(4)=0
   B(3)=1
   B(2)=0
   B(1)=0
   B(0)=1
   C(31)=1
   C(30)=0
   C(29)=0
   C(28)=1
   C(27)=1
   C(26)=0
   C(25)=0
   C(24)=0
   C(23)=1
   C(22)=0
   C(21)=1
   C(20)=1
   C(19)=1
   C(18)=0
   C(17)=1
   C(16)=0
   C(15)=1
   C(14)=1
   C(13)=0
   C(12)=1
   C(11)=1
   C(10)=1
   C(9)=0
   C(8)=0
   C(7)=1
   C(6)=1
   C(5)=1
   C(4)=1
   C(3)=1
   C(2)=1
   C(1)=1
   C(0)=0
   D(31)=0
   D(30)=0
   D(29)=0
   D(28)=1
   D(27)=0
   D(26)=0
   D(25)=0
   D(24)=0
   D(23)=0
   D(22)=0
   D(21)=1
   D(20)=1
   D(19)=0
   D(18)=0
   D(17)=1
   D(16)=0
   D(15)=0
   D(14)=1
   D(13)=0
   D(12)=1
   D(11)=0
   D(10)=1
   D(9)=0
   D(8)=0
   D(7)=0
   D(6)=1
   D(5)=1
   D(4)=1
   D(3)=0
   D(2)=1
   D(1)=1
   D(0)=0
   E(31)=1
   E(30)=1
   E(29)=0
   E(28)=0
   E(27)=0
   E(26)=0
   E(25)=1
   E(24)=1
   E(23)=1
   E(22)=1
   E(21)=0
   E(20)=1
   E(19)=0
   E(18)=0
   E(17)=1
   E(16)=0
   E(15)=1
   E(14)=1
   E(13)=1
   E(12)=0
   E(11)=0
   E(10)=0
   E(9)=0
   E(8)=1
   E(7)=1
   E(6)=1
   E(5)=1
   E(4)=1
   E(3)=0
   E(2)=0
   E(1)=0
   E(0)=0
   K1(31)=0
   K1(30)=1
   K1(29)=0
   K1(28)=1
   K1(27)=1
   K1(26)=0
   K1(25)=1
   K1(24)=0
   K1(23)=1
   K1(22)=0
   K1(21)=0
   K1(20)=0
   K1(19)=0
   K1(18)=0
   K1(17)=1
   K1(16)=0
   K1(15)=0
   K1(14)=1
   K1(13)=1
   K1(12)=1
   K1(11)=1
   K1(10)=0
   K1(9)=0
   K1(8)=1
   K1(7)=1
   K1(6)=0
   K1(5)=0
   K1(4)=1
   K1(3)=1
   K1(2)=0
   K1(1)=0
   K1(0)=1
   K2(31)=0
   K2(30)=1
   K2(29)=1
   K2(28)=0
   K2(27)=1
   K2(26)=1
   K2(25)=1
   K2(24)=0
   K2(23)=1
   K2(22)=1
   K2(21)=0
   K2(20)=1
   K2(19)=1
   K2(18)=0
   K2(17)=0
   K2(16)=1
   K2(15)=1
   K2(14)=1
   K2(13)=1
   K2(12)=0
   K2(11)=1
   K2(10)=0
   K2(9)=1
   K2(8)=1
   K2(7)=1
   K2(6)=0
   K2(5)=1
   K2(4)=0
   K2(3)=0
   K2(2)=0
   K2(1)=0
   K2(0)=1
   K3(31)=1
   K3(30)=0
   K3(29)=0
   K3(28)=0
   K3(27)=1
   K3(26)=1
   K3(25)=1
   K3(24)=1
   K3(23)=0
   K3(22)=0
   K3(21)=0
   K3(20)=1
   K3(19)=1
   K3(18)=0
   K3(17)=1
   K3(16)=1
   K3(15)=1
   K3(14)=0
   K3(13)=1
   K3(12)=1
   K3(11)=1
   K3(10)=1
   K3(9)=0
   K3(8)=0
   K3(7)=1
   K3(6)=1
   K3(5)=0
   K3(4)=1
   K3(3)=1
   K3(2)=1
   K3(1)=0
   K3(0)=0
   K4(31)=1
   K4(30)=1
   K4(29)=0
   K4(28)=0
   K4(27)=1
   K4(26)=0
   K4(25)=1
   K4(24)=0
   K4(23)=0
   K4(22)=1
   K4(21)=1
   K4(20)=0
   K4(19)=0
   K4(18)=0
   K4(17)=1
   K4(16)=0
   K4(15)=1
   K4(14)=1
   K4(13)=0
   K4(12)=0
   K4(11)=0
   K4(10)=0
   K4(9)=0
   K4(8)=1
   K4(7)=1
   K4(6)=1
   K4(5)=0
   K4(4)=1
   K4(3)=0
   K4(2)=1
   K4(1)=1
   K4(0)=0
End Sub
Sub Sha1_OutResult(ByRef A,ByRef B,ByRef C,ByRef D,ByRef E,ByRef R)
   Dim i
   Dim j
   Dim k
   Dim p
   R=""
   p=31
   For i=0 To 7 Step 1
       k=0
       For j=0 To 3 Step 1
           k=(k*2)+A(p)
           p=p-1
       Next
       R=R & Mid("0123456789ABCDEF",k+1,1)
   Next
   R=R & " "
   p=31
   For i=0 To 7 Step 1
       k=0
       For j=0 To 3 Step 1
           k=(k*2)+B(p)
           p=p-1
       Next
       R=R & Mid("0123456789ABCDEF",k+1,1)
   Next
   R=R & " "
   p=31
   For i=0 To 7 Step 1
       k=0
       For j=0 To 3 Step 1
           k=(k*2)+C(p)
           p=p-1
       Next
       R=R & Mid("0123456789ABCDEF",k+1,1)
   Next
   R=R & " "
   p=31
   For i=0 To 7 Step 1
       k=0
       For j=0 To 3 Step 1
           k=(k*2)+D(p)
           p=p-1
       Next
       R=R & Mid("0123456789ABCDEF",k+1,1)
   Next
   R=R & " "
   p=31
   For i=0 To 7 Step 1
       k=0
       For j=0 To 3 Step 1
           k=(k*2)+E(p)
           p=p-1
       Next
       R=R & Mid("0123456789ABCDEF",k+1,1)
   Next
End Sub
' Выполнение шага алгоритма
Sub SHA1_CalculateStep(ByRef A(),ByRef B(),ByRef C(),ByRef D(),ByRef E(),ByRef M(),ByRef K1,ByRef K2,ByRef K3,ByRef K4)
   Dim i
   Dim j
   Dim q
   Dim r
   Dim W(31,79)
   Dim T(31)
   Dim HA(31)
   Dim HB(31)
   Dim HC(31)
   Dim HD(31)
   Dim HE(31)
   For i=0 To 31 Step 1
       HA(i)=A(i)
       HB(i)=B(i)
       HC(i)=C(i)
       HD(i)=D(i)
       HE(i)=E(i)
   Next
   For i=0 To 15 Step 1
       For j=0 To 31 Step 1
           W(j,i)=M(j,i)
       Next
   Next
   For i=16 To 79 Step 1
       For j=0 To 30 Step 1
           W(j+1,i)=(W(j,i-3)+W(j,i-8)+W(j,i-14)+W(j,i-16))Mod 2
       Next
       W(0,i)=(W(31,i-3)+W(31,i-8)+W(31,i-14)+W(31,i-16))Mod 2
   Next
   For i=0 To 19 Step 1
       q=0
       For j=0 To 31 Step 1
           If(B(j)+C(j))>1 Then q=q+1 Else If(B(j)=0)AND(D(j)=1)Then q=q+1
           If j>=5 Then q=q+A(j-5) Else q=q+A(j+27)
           q=q+E(j)+K1(j)+W(j,i)
           T(j)=q Mod 2
           q=q\2
           E(j)=D(j)
           D(j)=C(j)
           If j<30 Then C(j)=B(j+2) Else C(j)=B(j-30)
       Next
       For j=0 To 31 Step 1
           B(j)=A(j)
           A(j)=T(j)
       Next
   Next
   For i=20 To 39 Step 1
       q=0
       For j=0 To 31 Step 1
           q=q+(B(j)+C(j)+D(j))Mod 2
           If j>=5 Then q=q+A(j-5) Else q=q+A(j+27)
           q=q+E(j)+K2(j)+W(j,i)
           T(j)=q Mod 2
           q=q\2
           E(j)=D(j)
           D(j)=C(j)
           If j<30 Then C(j)=B(j+2) Else C(j)=B(j-30)
       Next
       For j=0 To 31 Step 1
           B(j)=A(j)
           A(j)=T(j)
       Next
   Next
   For i=40 To 59 Step 1
       q=0
       For j=0 To 31 Step 1
           If(B(j)+C(j)+D(j))>1 Then q=q+1
           If j>=5 Then q=q+A(j-5) Else q=q+A(j+27)
           q=q+E(j)+K3(j)+W(j,i)
           T(j)=q Mod 2
           q=q\2
           E(j)=D(j)
           D(j)=C(j)
           If j<30 Then C(j)=B(j+2) Else C(j)=B(j-30)
       Next
       For j=0 To 31 Step 1
           B(j)=A(j)
           A(j)=T(j)
       Next
   Next
   For i=60 To 79 Step 1
       q=0
       For j=0 To 31 Step 1
           q=q+(B(j)+C(j)+D(j))Mod 2
           If j>=5 Then q=q+A(j-5) Else q=q+A(j+27)
           q=q+E(j)+K4(j)+W(j,i)
           T(j)=q Mod 2
           q=q\2
           E(j)=D(j)
           D(j)=C(j)
           If j<30 Then C(j)=B(j+2) Else C(j)=B(j-30)
       Next
       For j=0 To 31 Step 1
           B(j)=A(j)
           A(j)=T(j)
       Next
   Next
   q=0
   For i=0 To 31 Step 1
       q=q+HA(i)+A(i)
       A(i)=q Mod 2
       q=q\2
   Next
   q=0
   For i=0 To 31 Step 1
       q=q+HB(i)+B(i)
       B(i)=q Mod 2
       q=q\2
   Next
   q=0
   For i=0 To 31 Step 1
       q=q+HC(i)+C(i)
       C(i)=q Mod 2
       q=q\2
   Next
   q=0
   For i=0 To 31 Step 1
       q=q+HD(i)+D(i)
       D(i)=q Mod 2
       q=q\2
   Next
   q=0
   For i=0 To 31 Step 1
       q=q+HE(i)+E(i)
       E(i)=q Mod 2
       q=q\2
   Next
End Sub
Function SHA1_CountForString(ByRef s)
   Dim l
   Dim m
   Dim n
   Dim i
   Dim j
   Dim k
   Dim q
   Dim r
   Dim y
   Dim x
   Dim z(7)
   Dim G(31,15)
   Dim A(31)
   Dim B(31)
   Dim C(31)
   Dim D(31)
   Dim E(31)
   Dim K1(31)
   Dim K2(31)
   Dim K3(31)
   Dim K4(31)
   l=Len(s)
   m=l\64
   n=l Mod 64
   z(0)=(l Mod 32)*8
   z(1)=((l\32)Mod 256)
   z(2)=((l\8192)Mod 256)
   z(3)=((l\2097152)Mod 256)
   z(4)=((l\536870912)Mod 256)
   z(5)=0
   z(6)=0
   z(7)=0
   SHA1_InitConst A,B,C,D,E,K1,K2,K3,K4
   x=1
   For i=1 To m Step 1
       For j=0 To 63 Step 1
           y=j\4
           k=Asc(Mid(s,x,1))
           x=x+1
           r=24-((j Mod 4)*8)
           For q=1 To 8 Step 1
               G(r,y)=k Mod 2
               k=k\2
               r=r+1
           Next
       Next
       SHA1_CalculateStep A,B,C,D,E,G,K1,K2,K3,K4
   Next
   If n<56 Then
       m=m*64
       For j=0 To 63 Step 1
           y=j\4
           If j<n Then k=Asc(Mid(s,x,1))Else If j=n Then k=128 Else If j<56 Then k=0 Else k=z(63-j)
           x=x+1
           r=24-((j Mod 4)*8)
           For q=1 To 8 Step 1
               G(r,y)=k Mod 2
               k=k\2
               r=r+1
           Next
       Next
       SHA1_CalculateStep A,B,C,D,E,G,K1,K2,K3,K4
   Else
       r=0
       m=m*64
       For j=0 To 63 Step 1
           y=j\4
           If j<n Then k=Asc(Mid(s,x,1))Else If j=n Then k=128 Else k=0
           x=x+1
           r=24-((j Mod 4)*8)
           For q=1 To 8 Step 1
               G(r,y)=k Mod 2
               k=k\2
               r=r+1
           Next
       Next
       SHA1_CalculateStep A,B,C,D,E,G,K1,K2,K3,K4
       r=0
       For j=0 To 63 Step 1
           y=j\4
           If j<56 Then k=0 Else k=z(63-j)
           r=24-((j Mod 4)*8)
           For q=1 To 8 Step 1
               G(r,y)=k Mod 2
               k=k\2
               r=r+1
           Next
       Next
       SHA1_CalculateStep A,B,C,D,E,G,K1,K2,K3,K4
   End If
   SHA1_OutResult A,B,C,D,E,SHA1_CountForString
End Function
Function ConvertStringToUTF8(ByRef s)
   Dim l
   Dim i
   Dim j
   ConvertStringToUTF8=""
   l=Len(s)
   For i=1 To l Step 1
       j=AscW(Mid(s,i,1))
       If j<128 Then
           ConvertStringToUTF8=ConvertStringToUTF8 & Chr(j)
       ElseIf j<2048 Then
           ConvertStringToUTF8=ConvertStringToUTF8 & Chr(192+(j\64)) & Chr((j Mod 64)+128)
       Else
           ConvertStringToUTF8=ConvertStringToUTF8 & Chr((j\2048)+224) & Chr(((j Mod 2048)\64)+128) & Chr((j Mod 64)+128)
       End If
   Next
End Function
41 mvgfirst
 
07.04.13
19:38
(40) Спасибо большое. Но я уже решил это через джаваскрипт.
Щас другая проблема.
При работе на клиенте - я получал base64 строку используя специальный метод компоненты StringsNatve, все работало правильно - банк у меня пакеты закодированные принимал.

Но т.к. компонента работать на сервере не желает - решил воспользоваться методом 1С "base64Строка" - но он принимает на вход только двоичные данные.
Я сохранил строку в файл и файл подал через "Новый ДвоичныеДанные" на вход этому методу. В итоге банк не принимает пакет.

Сравнил результаты кодирования методом компоненты и метдом платормы - результаты разные.
42 Torquader
 
07.04.13
19:40
(41) Ну а если собрать строку BASE64 вручную - там вообще ничего сложного нет. Я на 1С7.7 BASE 95 писал - BASE64 проще.
Другое дело - как кодируется русский язык перед записью в BASE64 ?
43 Diversus
 
07.04.13
19:59
(0) Тоже сталкивался мне нужно было найти MD5 и SHA-512. Процедуру получения MD5 можно найти в БСП в модуле отправки СМС.
Как сделал SHA-512 можно посмотреть по ссылке http://sys1c.ru/other/90-sha5121s.html

Для SHA-1 можно использовать тот же подход...
44 mvgfirst
 
07.04.13
20:42
(43) А можно эту процедуру сюда запостить?
Я БСП не ставил себе, видел из далека - но там все так запутанно что с наскоку и не разберешся. Мне просто интересно - как они этот решили?
45 mvgfirst
 
07.04.13
21:11
Вот решил вопрос таким вот методом.

Функция Base64ВСтрку(КодируемаяСтрока) Экспорт
   Хеш="";
   Попытка
       ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl");
       ScrptCtrl.Language = "JScript";
       ScrptCtrl.AddCode("function base64encode(str) {
       |    // Символы для base64-преобразования
       |    var b64chars = ""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="";
       |    var b64encoded = """";
       |    var chr1, chr2, chr3;
       |    var enc1, enc2, enc3, enc4;
       |
       |    for (var i=0; i<str.length;) {
       |        chr1 = str.charCodeAt(i++);
       |        chr2 = str.charCodeAt(i++);
       |        chr3 = str.charCodeAt(i++);
       |
       |        enc1 = chr1 >> 2;
       |        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
       |
       |        enc3 = isNaN(chr2) ? 64:(((chr2 & 15) << 2) | (chr3 >> 6));
       |        enc4 = isNaN(chr3) ? 64:(chr3 & 63);
       |
       |        b64encoded += b64chars.charAt(enc1) + b64chars.charAt(enc2) +
       |                      b64chars.charAt(enc3) + b64chars.charAt(enc4);
       |    }
       |    return b64encoded;
       |}");
       Хэш = ScrptCtrl.Run("base64encode", КодируемаяСтрока);
   Исключение
       Сообщить(ОписаниеОшибки(), );
   КонецПопытки;
   ScrptCtrl = "";
   Возврат Хэш;
КонецФункции // Base64ВСтрку()



Сейчас все три скрипта прикручу к регламентному заданию ну и посмотрим взлетит/невзлетит....
46 Torquader
 
07.04.13
21:33
(45) JavaScript страдает невозможностью передачи параметров по ссылке - по этому я всегда использую VbScript - хотя BASE64 можно написать и на 1С.
И не забываем, что для русских букв charCodeAt возвращает коды в районе 1024, что в BASE64 не засунешь - то есть нужно сначала переводить в UTF-8, а потом полученные байты переводить в BASE64 - иначе будет "забавно".
47 sttt
 
07.04.13
22:08
можно и хранимую процедуру сделать:

using System.Security.Cryptography;
using System;
using System.Text;
using System.Data;
using System.Data.SqlTypes;

namespace Md5Hash
{
   public class Md5Class
   {
       [Microsoft.SqlServer.Server.SqlProcedure]
       public static void HashString(SqlString value, out SqlString result)
       {
           string str = value.ToString().Trim();
           HashAlgorithm mhash = mhash = new MD5CryptoServiceProvider();
           byte[] bytValue = System.Text.Encoding.UTF8.GetBytes(str);
           byte[] bytHash = mhash.ComputeHash(bytValue);
           mhash.Clear();

           StringBuilder sBuilder = new StringBuilder();

           for (int i = 0; i < bytHash.Length; i++)
           {
               sBuilder.Append(bytHash[i].ToString("x2"));
           }

           result = sBuilder.ToString();
       }
   }
}

компилим:
%SYSTEMROOT%\Microsoft.NET\Framework\v2.0.50727\csc.exe /target:library c:\xp_md5.cs

получим xp_md5.dll

потом включаем разрешение на SQL сервер использование CLR
sp_configure 'clr enabled', 1
go
reconfigure
go

подключаем наш модуль:

CREATE ASSEMBLY CLRFunctions FROM 'C:\xp_md5.dll'
go

создадим пользовательскую функцию:

CREATE FUNCTION [dbo].[fn_md5] (@data TEXT)
RETURNS CHAR(32) AS
BEGIN
 DECLARE @hash CHAR(32)
 EXEC master.dbo.xp_md5 @data, -1, @hash OUTPUT
 RETURN @hash
END
48 mvgfirst
 
07.04.13
22:19
(46) По идее - я не буду использовать русские символы в тех данных которые кодирую с помощью своих функций
В этом мне повезло

Однако ваши замечания справедливы. Но я не такой "суровый" программист что бы вытворять такое....

я больше на уровне бизнес-логики... поэтому очень рад буду если наконец-то появится внешняя компонента реализующая все эти механизмы и с русскими буквами в том числе.
49 mvgfirst
 
08.04.13
12:06
Почему вот это:

ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl");

не работает когда вызывается из регламентного задания

НО работает когда вызываю из обработки на клиенте?

И клиент и сервер запущены на одной машине. Сервер х64
50 mvgfirst
 
08.04.13
12:07
Выдает ошибку "Ошибка при вызове конструктора (COMОбъект): Class not registered: Class not registered"
51 sapphire
 
08.04.13
12:10
(49) MSScriptControl.ScriptControl не поддерживается на серверных осях х64
52 sapphire
 
08.04.13
12:15
53 sapphire
 
08.04.13
12:17
Там основная идея в использовании
objCrypt = Новый COMОбъект("System.Security.Cryptography.MD5CryptoServiceProvider");
54 sapphire
 
08.04.13
12:18
Так же для SHA1:

objCrypt = Новый COMОбъект("System.Security.Cryptography.SHA1CryptoServiceProvider");
55 sapphire
 
08.04.13
12:18
56 mvgfirst
 
08.04.13
12:22
(55) Пипец, я еле с javascript разобрался - у меня два дня на это ушло - эту хрень мне точно не разобрать...
57 sapphire
 
08.04.13
12:28
(56) Что там разбирать-то?
по ссылке в (52), за что ему, автору, спасиб:
Функция DecToHex(Знач Число)
   Если Число = 0 Тогда Возврат "00"; КонецЕсли;
   _Число = Число;
   База = 16;
   Пока _Число <> 0 Цикл
       Поз =_Число % База;
       Результат = Сред("0123456789abcdef", Поз + 1, 1) + Результат;
       _Число = Цел(_Число / База);
   КонецЦикла;
   Если Число < База Тогда Результат = "0" + Результат; КонецЕсли;
   Возврат Результат;
КонецФункции // DecToHex()

Функция  ПолучитьMD5ХэшФайла(ХранилищеЗначенияИлиПутьКФайлу) Экспорт
   Если ТипЗнч(ХранилищеЗначенияИлиПутьКФайлу) = Тип("ХранилищеЗначения") Тогда
       ПутьКФайлу = ПолучитьИмяВременногоФайла();
       ХранилищеЗначенияИлиПутьКФайлу.Получить().Записать(ПутьКФайлу);
   Иначе
       ПутьКФайлу = ХранилищеЗначенияИлиПутьКФайлу;
   КонецЕсли;
       adTypeBinary = 1;
   
   objCrypt = Новый COMОбъект("System.Security.Cryptography.MD5CryptoServiceProvider");
   objStream = Новый COMОбъект("ADODB.Stream");
   objStream.Open();
   objStream.Type = adTypeBinary;
   objStream.LoadFromFile(ПутьКФайлу);
   HashArray = objCrypt.ComputeHash_2(objStream.Read());
   Хэш = "";
   Для каждого Число Из HashArray Цикл
       Хэш = Хэш + DecToHex(Число);
   КонецЦикла;
   Возврат Хэш;
КонецФункции
58 mvgfirst
 
08.04.13
12:48
Мне еще нужны:
SHA1

и Base64Строка (как я писал выше та что создается стандартной 1С-вской функцией - непринимается банком)
59 sapphire
 
08.04.13
12:49
(58) Ты читать умеешь?
см (54)
60 mvgfirst
 
08.04.13
12:52
Это я видел.

Как мне с помощью этого получить Base64 из строки?
61 sapphire
 
08.04.13
12:53
objCrypt = Новый COMОбъект("System.Security.Cryptography.ToBase64Transform");
62 sapphire
 
08.04.13
12:53
63 sapphire
 
08.04.13
12:55
(60) Ты уже определись, что именно нужно, по-уму, спасибо тому товарищу, в классе System.Security.Cryptography достаточно методов для реализации.
64 mvgfirst
 
08.04.13
12:58
Т.е. все днные которые мне нужно будет вычислять - мне придется писать в файл.
И судя по условию моей задачи у меня будет минимум 1001 запись и чтение файла.

А так что бы не писать в файл, нельзя?
65 1Снег
 
08.04.13
13:00
А почему никто не предлагает только на 1С решение, это же чисто математическая задача
66 mvgfirst
 
08.04.13
13:04
(65) Решение на 1С у меня есть (нашел в инете и на Инфостарте)
Но это настолько медленно - что "не лезет ни в какие ворота!"
В маштабах вычисления 1-го Хеша - это еще терпимо

Но когда мне нужно для 100 файлов посчитать 1000 хешей для каждого - это занимает пол дня.
67 sapphire
 
08.04.13
13:19
(64) Можно и не писать в файл.
68 sapphire
 
08.04.13
13:19
(66) Да уж меня позабавило то, как мой недокод расползся по инетам...
69 sapphire
 
08.04.13
13:21
Вообще, есть в 1С такой объект как "Криптография"...
70 sapphire
 
08.04.13
13:22
(65) Потому что медленно...
71 mvgfirst
 
08.04.13
13:34
(67) Не писать? Это как? Передавать в ComputeHash строку?
72 mvgfirst
 
08.04.13
14:22
(69)В 8.2 есть? Точно?
73 sapphire
 
08.04.13
14:37
(72) Да, есть и оно как раз использует System.Security.Cryptography
74 sapphire
 
08.04.13
14:42
(71) Массив байтовый
75 mvgfirst
 
08.04.13
15:10
(74) Как получить битовый массив в 1с?

Можно пример?
76 Torquader
 
09.04.13
01:35
Я вчера написал SHA1 на языке 1С. Причём используя только переменные, в которых хранится 0 или 1. Все битовые операции перевёл в операции 1С.
Но, 1С га..но!
Потому как код получился на 3 мегабайта. Когда я это вставил в обработку, оно даже скомпилялось, только где-то строки порезались - и работать не стало.
Самое смешное - при попытке удалить код из модуля формы (путём выделения и нажатия DEL) словил глюк - конфигуратор виснет намертво и ничего не делает.
Пытался удалять по частям - из 70 с лишним тысяч строк осталось 5 тысяч, и всё равно повис, сволочь такая.
В общем - 1С просто не годится, чтобы на ней что-то можно было бы написать нормальное.
P.S. в прошлый раз md5 в 1С77 запихивал - напоролся на то, что там есть ограничение по длине строки, чтоб ей пусто было.
77 Torquader
 
09.04.13
03:00
Короче - 1000 раз за 39 секунд - устроит ?
Только код 1С и никаких внешних объектов и т.п.
Без вывода результата на экран получается 30 секунд.

Короче - этот код на VbScript запускается и в файле мы получаем код для 1С, который по объёму гораздо длиннее.


' попробуем написать SHA1 на 1С.
' сначала смещения для выравнивания (чтобы код смотрелся лучше)
Dim vbTab2
vbTab2=vbTab & vbTab
Dim vbTab3
vbTab3=vbTab2 & vbTab
Dim vbTab4
vbTab4=vbTab3 & vbTab
Dim vbTab5
vbTab5=vbTab4 & vbTab

' теперь объект для записи файла
Dim Fso
Dim File
Set Fso=CreateObject("Scripting.FileSystemObject")
' именно в этом файле в директории сценария вы увидите код
' который нужно вставить в 1С
Set File=Fso.CreateTextFile("SHA1S.TXT",True,False)

' отображение ошибки, если мы капитально накосячили
' на самом деле не понадобилось, но для "бизонов" оставим
Sub ShowError(ByRef ErrStr)
   File.Close()
   MsgBox ErrStr,0,"Ошибка"
   WScript.Quit()
End Sub

' данная процедура генерирует код, который инициализирует
' наши битовые переменные начальными значениями
Sub InitShaVar(ByRef VarName,ByRef HexValue)
   Dim i
   Dim j
   Dim k
   ' проверяем, что строка написана верно
   If Len(HexValue)<>8 Then
       ShowError "Неверное значение для переменной:" & HexValue
   End If
   ' строка из восьми шестнадцатиричных цифр (только заглавные буквы)
   For i=1 To 8 Step 1
       j=Mid(HexValue,i,1)
       ' маленькие буквы мы игнорируем
       j=InStr(1,"0123456789ABCDEF",j,vbBinaryCompare)
       If j=0 Then
           ShowError "Неверный символ в значении переменной:" & HexValue
       End If
       j=j-1 ' не забываем про смещение (строки почему-то начинаются с единицы)
       k=28-(i-1)*4
       File.WriteLine(vbTab & "Sha_" & VarName & "_" & CStr(k) & "=" & CStr(j Mod 2) & ";")
       k=k+1
       File.WriteLine(vbTab & "Sha_" & VarName & "_" & CStr(k) & "=" & CStr((j\2)Mod 2) & ";")
       k=k+1
       File.WriteLine(vbTab & "Sha_" & VarName & "_" & CStr(k) & "=" & CStr((j\4)Mod 2) & ";")
       k=k+1
       File.WriteLine(vbTab & "Sha_" & VarName & "_" & CStr(k) & "=" & CStr(j\8) & ";")
   Next
End Sub

' когда у нас в код добавляется костанта, нам нужно достать из неё бит
' он будет железно закодирован в коде
Function GetBitFromNumber(ByRef HexValue,ByRef BitNumber)
   If Len(HexValue)<>8 Then
       ShowError "Неверное значение числа для извлечения бита:" & HexValue
   End If
   If(BitNumber<0)OR(BitValue>31)Then
       ShowError "Нереальный номер бита:" & CStr(BitNumber)
   End If
   i=Mid(HexValue,8-(BitNumber\4),1)
   i=InStr(1,"0123456789ABCDEF",i,vbBinaryCompare)
   If i=0 Then
       ShowError "Неверный символ для числа:" & HexValue
   End If
   i=i-1
   j=BitNumber Mod 4 ' количество сдвигов
   While j>0
       i=i\2
       j=j-1
   Wend
   GetBitFromNumber=CStr(i Mod 2)
End Function

' процедура копирования одной переменной в другую
' на самом деле их по 32 штуки
Sub CopyBitVar(ByRef Tab,ByRef Target,ByRef Source)
   Dim i
   For i=0 To 31 Step 1
       File.WriteLine(Tab & Target & "_" & CStr(i) & "=" & Source & "_" & CStr(i) & ";")
   Next
End Sub

' расчёт суммы - у нас переменные битовые, так что нужно работать с переносом
Sub CountSum(ByRef Tab,ByRef VarName)
   Dim i
   ' инициализаруем значение переноса
   File.WriteLine(Tab & "лч=0;")
   For i=0 To 31 Step 1
       ' выполняем сложение очередного бита
       File.WriteLine(Tab & "лч=лч+Sha_" & VarName & "_" & CStr(i) & "+loc" & VarName & "_" & CStr(i) & ";")
       ' младший бит полученного результата идёт в результат
       File.WriteLine(Tab & "Sha_" & VarName & "_" & CStr(i) & "=лч%2;")
       ' остальные биты смещаем вправо, если, конечно, бит не последний
       If i<>31 Then
           File.WriteLine(Tab & "лч=Цел(лч/2);")
       End If
   Next
End Sub

' основной шаг алгоритма (то есть всё то, что описано, здесь и делается)
Sub ProcessSha1Step(ByRef Tab)
   Dim i
   Dim j
   Dim k
   Dim s
   ' сначала нужно инициализировать переменные для массива значений
   ' изначально у нас блок данных - строка из 512 символов (только 0 и 1)
   ' нужно их перевести в цифры, так как с цифрами проще работать
   For i=1 To 512 Step 1
       ' у нас сначала идут старшие, потом младшие
       j=(i-1)\32 ' номер слова
       k=31-(i-1)Mod 32 ' номер бита в слове
       File.WriteLine(Tab & "W_" & CStr(k) & "_" & CStr(j) & "=КодСимвола(лстр," & CStr(i) & ")-48;")
   Next
   ' теперь нужно рассчитать остальные согласно формуле
   For i=16 To 79 Step 1
       ' не забываем про сдвиг - для нас это просто смещение номера переменной
       For j=0 To 30 Step 1
           File.WriteLine(Tab & "W_" & CStr(j+1) & "_" & CStr(i) & "=(W_" & CStr(j) & "_" & CStr(i-3) & "+W_" & CStr(j) & "_" & CStr(i-8) & "+W_" & CStr(j) & "_" & CStr(i-14) & "+W_" & CStr(j) & "_" & CStr(i-16) & ")%2;")
       Next
       File.WriteLine(Tab & "W_0_" & CStr(i) & "=(W_31_" & CStr(i-3) & "+W_31_" & CStr(i-8) & "+W_31_" & CStr(i-14) & "+W_31_" & CStr(i-16) & ")%2;")
   Next
   ' сохраняем числа в массиве для выполнения сложения в конце
   ' другими словами, мы делаем копирование из глобальных переменных в локальные
   For i=1 To 5 Step 1
       s=Mid("ABCDE",i,1)
       CopyBitVar Tab,"loc" & s,"Sha_" & s
   Next
   ' и, наконец, переходим к основному алгоритму, который разложим на биты
   For i=0 To 79 Step 1
       ' так как у нас сложение, то без переноса не обойтись
       File.WriteLine(Tab & "лч=0;")
       For j=0 To 31 Step 1
           ' мы определим функцию и константу
           ' функцию с языка битов переведём в числовой эквивалент
           If i<20 Then
               File.WriteLine(Tab & "Если locB_" & CStr(j) & "+locC_" & CStr(j) & ">1 Тогда лч=лч+1;ИначеЕсли(locB_" & CStr(j) & "=0)И(locD_" & CStr(j) & "=1)Тогда лч=лч+1;КонецЕсли;")
               s="5A827999"
           ElseIf i<40 Then
               File.WriteLine(Tab & "лч=лч+(locB_" & CStr(j) & "+locC_" & CStr(j) & "+locD_" & CStr(j) & ")%2;")
               s="6ED9EBA1"
           ElseIf i<60 Then
               File.WriteLine(Tab & "Если(locB_" & CStr(j) & "+locC_" & CStr(j) & "+locD_" & CStr(j) & ")>1 Тогда лч=лч+1;КонецЕсли;")
               s="8F1BBCDC"
           ElseIf i<80 Then
               File.WriteLine(Tab & "лч=лч+(locB_" & CStr(j) & "+locC_" & CStr(j) & "+locD_" & CStr(j) & ")%2;")
               s="CA62C1D6"
           Else
               ShowError "Переполнение счётчика цикла"
           End If
           ' сдвиг на пять - это просто выбор других битов
           If j>=5 Then k=j-5 Else k=j+27
           File.WriteLine(Tab & "лч=лч+locA_" & CStr(k) & "+locE_" & CStr(j) & "+" & GetBitFromNumber(s,j) & "+W_" & CStr(j) & "_" & CStr(i) & ";")
           ' аналогичная суммированию обработка переноса
           File.WriteLine(Tab & "locT_" & CStr(j) & "=лч%2;")
           If j<>31 Then
               File.WriteLine(Tab & "лч=Цел(лч/2);")
           End If
       Next
       ' выполняем простое копирование
       CopyBitVar Tab,"locE","locD"
       CopyBitVar Tab,"locD","locC"
       ' присвоение со сдвигом (просто копируем другие биты)
       For j=0 To 31 Step 1
           If j<30 Then k=j+2 Else k=j-30
           File.WriteLine(Tab & "locC_" & CStr(j) & "=locB_" & CStr(k) & ";")
       Next
       ' теперь остальные присвоения
       CopyBitVar Tab,"locB","locA"
       CopyBitVar Tab,"locA","locT"
   Next
   ' теперь расчёт суммы со старым значением с переносом битов
   For i=1 To 5 Step 1
       s=Mid("ABCDE",i,1)
       CountSum Tab,s
   Next
End Sub

' строка из нужного количества нулей могла быть бы записана константой
' но я программист, и мне пробел давить лениво
Function OutZeroString(ByRef ZerCount)
   Dim i
   OutZeroString=""
   For i=1 To ZeroCount Step 1
       OutZeroString=OutZeroString & "0"
   Next
End Function

' данный блок создаёт текстовый вывод результата
' если кого-то не устраивает - просто переписываем под себя
Sub CreateOutResult()
   Dim i
   Dim j
   Dim v
   Dim k
   Dim t
   File.WriteLine(vbTab & "Возврат ")
   For i=1 To 5 Step 1
       v="Sha_" & Mid("ABCDE",i,1) & "_"
       If i<>1 Then
           File.WriteLine(vbTab2 & """ ""+")
       End If
       For j=1 To 8 Step 1
           k=j*4
           If(i=5)AND(j=8)Then t=";" Else t="+"
           File.WriteLine(vbTab2 & "мфЦифраПоЧетремБитам(" & v & CStr(35-k) & "," & v & CStr(34-k) & "," & v & CStr(33-k) & "," & v & CStr(32-k) & ")" & t )
       Next
   Next
End Sub

' ну и теперь соберём весь алгоритм
Dim i
Dim j
Dim k
' вспомогательная функция для вывода результата
File.WriteLine("Функция мфЦифраПоЧетремБитам(пчБ3,пчБ2,пчБ1,пчБ0)")
File.WriteLine(vbTab & "лч=(пчБ3*8)+(пчБ2*4)+(пчБ1*2)+пчБ0;")
File.WriteLine(vbTab & "Возврат Сред(""0123456789ABCDEF"",лч+1,1);")
File.WriteLine("КонецФункции")
' перевод байта в строку битов
File.WriteLine("Функция мфБайтВСтрокуБитов(пчБайт)")
File.WriteLine(vbTab & "лстрРезультат="""";")
File.WriteLine(vbTab & "лчЗначение=пчБайт;")
File.WriteLine(vbTab & "Для лч=1 По 8 Цикл")
File.WriteLine(vbTab2 & "лстрРезультат=Строка(лчЗначение%2)+лстрРезультат;")
File.WriteLine(vbTab2 & "лчЗначение=Цел(лчЗначение/2);")
File.WriteLine(vbTab & "КонецЦикла;")
File.WriteLine(vbTab & "Возврат лстрРезультат;")
File.WriteLine("КонецФункции")
' преобразование числа (длины строки) в строку битов для записи в конец
File.WriteLine("Функция мфДлинаВСтрокуБитов(пчДлина)")
File.WriteLine(vbTab & "лстрРезультат="""";")
File.WriteLine(vbTab & "лчЗначение=пчДлина;")
File.WriteLine(vbTab & "Для лч=1 По 64 Цикл")
File.WriteLine(vbTab2 & "лстрРезультат=Строка(лчЗначение%2)+лстрРезультат;")
File.WriteLine(vbTab2 & "лчЗначение=Цел(лчЗначение/2);")
File.WriteLine(vbTab & "КонецЦикла;")
File.WriteLine(vbTab & "Возврат лстрРезультат;")
File.WriteLine("КонецФункции")
' а вот и наша замечательная функция - несколько мегабайт кода
File.WriteLine("Функция Sha1Diggest(пстрСтрокаДляРасчета)")
' сначала нужно измерить длину строки в байтах
' но у нас строка Unicode, а мы хотим перевести её в UTF-8
File.WriteLine(vbTab & "лчДлинаИсходнойСтроки=СтрДлина(пстрСтрокаДляРасчета);")
' теперь нужно инициализировать служебные переменные SHA1 алгоритма
InitShaVar "A","67452301"
InitShaVar "B","EFCDAB89"
InitShaVar "C","98BADCFE"
InitShaVar "D","10325476"
InitShaVar "E","C3D2E1F0"
' обнуляем размер битовой строки (она потом ляжет в восемь байт)
File.WriteLine(vbTab & "лстр="""";")
File.WriteLine(vbTab & "лчДлинаБуфера=0;")
File.WriteLine(vbTab & "лчДлинаИсходногоСообщения=0;")
' теперь выполняем тело алгоритма
File.WriteLine(vbTab & "лчПозицияЧтенияСтроки=1;")
' читаем переданную строку посимвольно в бесконечном цикле (прервём его по окончанию строки)
' можно, конечно, записать и по-другому (здесь я ступил, но переписывать лень)
File.WriteLine(vbTab & "Пока Истина Цикл")
File.WriteLine(vbTab2 & "Если лчПозицияЧтенияСтроки>лчДлинаИсходнойСтроки Тогда Прервать;КонецЕсли;")
' получаем код символа - как известно, они в Unicode, то есть UTF-16
File.WriteLine(vbTab2 & "лчТекущийСимвол=КодСимвола(пстрСтрокаДляРасчета,лчПозицияЧтенияСтроки);")
File.WriteLine(vbTab2 & "лчПозицияЧтенияСтроки=лчПозицияЧтенияСтроки+1;")
' переведём его в UTF-8
File.WriteLine(vbTab2 & "Если лчТекущийСимвол<128 Тогда")
File.WriteLine(vbTab3 & "лстр=лстр+мфБайтВСтрокуБитов(лчТекущийСимвол);")
File.WriteLine(vbTab3 & "лчДлинаБуфера=лчДлинаБуфера+8;")
File.WriteLine(vbTab3 & "лчДлинаИсходногоСообщения=лчДлинаИсходногоСообщения+8;")
File.WriteLine(vbTab2 & "ИначеЕсли лчТекущийСимвол<2048 Тогда")
File.WriteLine(vbTab3 & "лстр=лстр+мфБайтВСтрокуБитов(192+Цел(лчТекущийСимвол/64))+мфБайтВСтрокуБитов((лчТекущийСимвол%64)+128);")
File.WriteLine(vbTab3 & "лчДлинаБуфера=лчДлинаБуфера+16;")
File.WriteLine(vbTab3 & "лчДлинаИсходногоСообщения=лчДлинаИсходногоСообщения+16;")
File.WriteLine(vbTab2 & "Иначе")
File.WriteLine(vbTab3 & "лстр=лстр+мфБайтВСтрокуБитов(Цел(лчТекущийСимвол/2048)+224)+мфБайтВСтрокуБитов(Цел((лчТекущийСимвол%2048)/64)+128)+мфБайтВСтрокуБитов((лчТекущийСимвол%64)+128);")
File.WriteLine(vbTab3 & "лчДлинаБуфера=лчДлинаБуфера+24;")
File.WriteLine(vbTab3 & "лчДлинаИсходногоСообщения=лчДлинаИсходногоСообщения+24;")
File.WriteLine(vbTab2 & "КонецЕсли;")
' если есть готовый блок, то есть кормим алгоритму
File.WriteLine(vbTab2 & "Если лчДлинаБуфера>=512 Тогда")
' здесь мы выполняем общий расчёт по алгоритму
ProcessSha1Step vbTab3
' не забываем, что при добавлении сразу трёх символов может остаться хвост
File.WriteLine(vbTab3 & "Если лчДлинаБуфера>512 Тогда")
File.WriteLine(vbTab4 & "лстр=Сред(лстр,513);")
File.WriteLine(vbTab4 & "лчДлинаБуфера=лчДлинаБуфера-512;")
File.WriteLine(vbTab3 & "Иначе")
File.WriteLine(vbTab4 & "лстр="""";")
File.WriteLine(vbTab4 & "лчДлинаБуфера=0;")
File.WriteLine(vbTab3 & "КонецЕсли;")
File.WriteLine(vbTab2 & "КонецЕсли;")
File.WriteLine(vbTab & "КонецЦикла;")
' если набор битов (точнее байт) закончился, то смотрим, что у нас есть
File.WriteLine(vbTab & "Если лчДлинаБуфера<448 Тогда")
File.WriteLine(vbTab2 & "лстр=лстр+""10000000"";")
File.WriteLine(vbTab2 & "лчДлинаБуфера=лчДлинаБуфера+8;")
File.WriteLine(vbTab2 & "Пока лчДлинаБуфера<448 Цикл")
File.WriteLine(vbTab3 & "лстр=лстр+""00000000"";")
File.WriteLine(vbTab3 & "лчДлинаБуфера=лчДлинаБуфера+8;")
File.WriteLine(vbTab2 & "КонецЦикла;")
File.WriteLine(vbTab2 & "лстр=лстр+мфДлинаВСтрокуБитов(лчДлинаИсходногоСообщения);")
File.WriteLine(vbTab & "Иначе")
File.WriteLine(vbTab2 & "лстр=лстр+""10000000"";")
File.WriteLine(vbTab2 & "лчДлинаБуфера=лчДлинаБуфера+8;")
File.WriteLine(vbTab2 & "Пока лчДлинаБуфера<512 Цикл")
File.WriteLine(vbTab3 & "лстр=лстр+""00000000"";")
File.WriteLine(vbTab3 & "лчДлинаБуфера=лчДлинаБуфера+8;")
File.WriteLine(vbTab2 & "КонецЦикла;")
ProcessSha1Step vbTab2
File.WriteLine(vbTab2 & "лстр=""" & OutZeroString(448) & """+мфДлинаВСтрокуБитов(лчДлинаИсходногоСообщения);")
File.WriteLine(vbTab & "КонецЕсли;")
ProcessSha1Step vbTab
' теперь нужно вывести результат посимвольно
CreateOutResult
File.WriteLine("КонецФункции")
File.Close()
' скажем, что мы справились
MsgBox "OK",0,"OK"
78 mvgfirst
 
09.04.13
10:13
(76) Огоромное спасибо за усилия, но 39 секунд не устроит.
Код который я нашел на javascript выполняет это за 4 секунды
(компонента по прежнему показывает результат меньше секунды)
И еще на инфостарте, один уважаемый человек пообещал скомпилить библиотечку под х64
Так что ждемс....
79 kvk
 
09.04.13
10:35
(37) Если нужна кроссплатформенность, то может из этого что получится (скорость на полгиговом файле та же, что и на PowerShell):


   py = "# -*- coding: UTF-8 -*-
   |# Python 3.2.4
   |
   |import base64
   |import hashlib
   |import os
   |import sys
   |
   |def md5sum(filename):
   |    'md5 sum: http://stackoverflow.com/questions/1131220/get-md5-hash-of-big-files-in-python#answer-11143944'
   |    md5 = hashlib.md5()
   |    with open(filename,'rb') as f:
   |        for chunk in iter(lambda: f.read(128*md5.block_size), b''):
   |             md5.update(chunk)
   |    return md5.hexdigest()
   |
   |if __name__ == '__main__':
   |    input = sys.argv[1]
   |    base_name = os.path.splitext(input)[0]
   |    output = base_name + '.b64'
   |    md5 = base_name + '.md5'
   |    
   |    with open(input, 'rb') as i:
   |        with open(output, 'wb') as o:
   |            base64.encode(i, o)
   |    
   |    for i in range(1000):
   |        md5sum(output)
   |    
   |    with open(md5, 'w') as m:
   |        m.write(md5sum(output))";
   
   ВременныйФайл = ПолучитьИмяВременногоФайла("py");
   Скрипт = Новый ЗаписьТекста(ВременныйФайл);
   Скрипт.Записать(py);
   Скрипт.Закрыть();
   
   ФайлСкрипт = Новый Файл(ВременныйФайл);
   Шелл = Новый COMОбъект("WScript.Shell");
   Шелл.Run("python """ + ФайлСкрипт.ПолноеИмя + """ """ + ФайлСкрипт.ПолноеИмя + """", 0, Истина);
   //УдалитьФайлы(ФайлСкрипт.Путь, ФайлСкрипт.ИмяБезРасширения + ".*");
   ТамЖеОтправитьМожно = "
   |context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
   |context.verify_mode = ssl.CERT_REQUIRED
   |context.load_verify_locations(DYNDNS_MEMBERS_CACERT)
   |conn = http.client.HTTPSConnection(DYNDNS_MEMBERS, timeout=20, context=context)
   |conn.request('GET', '/nic/update?hostname=' + DYNDNS_HOST_NAMES + '&myip=' + new_address +
   |    ('&offline=yes' if offline else ''), None, headers)
   |response = conn.getresponse()
   |conn.close()";
80 mvgfirst
 
09.04.13
10:45
(79) Кросплатформенность - это не приоритет вообще. Просто если у решения она будет - значит решению дополнительный "+"

А по коду вопорос, для его использования создается:

Шелл = Новый COMОбъект("WScript.Shell");

Разве COMОбъект - это кроссплатформенно? Спрашиваю, потом что неуверен что это сработает в Линуксовом варианте сервера.
81 kvk
 
09.04.13
10:51
Попробуй ЗапуститьПриложение. Это только набросок, если есть желание на пайтоне сделать и кроссплатформенно это скорее всего будет всего лишь одна из проблем.
82 Torquader
 
09.04.13
13:19
(81) Если через "ЗапуститьПриложение", то проще всего написать программу на Си, используя стандартные функции чтения-записи файлов, потом скомпилять под разные платформы.
В 1С просто выгрузить нужные данные в текстовый файл, запустить программу и подождать, пока она создаст файл с результатом - скорость будет очень даже ничего.
Кстати, никто не мешает использовать готовые OpenSource решения.
http://gnuwin32.sourceforge.net/packages/coreutils.htm
А в linux-е оно должно быть в командной строке вообще.
83 Torquader
 
09.04.13
15:00
Самое интересное, что если собрать код в несколько строк (а не каждая операция на отдельной строке), то время выполнения существенно сокращается, как ни странно.
Так что в
v8: Преобразование текста модуля в одну строку
что-то есть.