Для расчета контрольной суммы по XML-файлу выделяется строка символов, между правой угловой скобкой открывающего тега <MAIN> (не включая ее) и заканчивающаяся и левой угловой скобкой закрывающего тега </MAIN> (не включая ее).
Символы пробелов, табуляции, возврата каретки и перевода строки не сохраняются в полученной строке и не участвуют в расчете контрольной суммы.
Далее по этой строке ведется подсчет контрольной суммы в соответствии с алгоритмом, указанным в пункте 8.1 настоящего документа.
Полученное значение заносится в атрибут chsm.
8.1. Алгоритм расчета контрольной суммы по строке символов
В расчете контрольной суммы по выделенной строке применяется алгоритм Secure Hash Algorithm (SHA) стандарта Secure Hash Standard (SHS).
Алгоритм SHA (Secure Hash Algorithm) стандарта безопасного хеширования (Secure Hash Standard, SHS).
В зависимости от выходного хеш-значения выделяют следующие виды SHA:
SHA1 - выходное значение 160 бит;
SHA256 - выходное значение 256 бит;
SHA512 - выходное значение 512 бит;
SHA384 - выходное значение 384 бита.
Стандарт ИСО - ISO/EEC 10118-3:2004
(http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=39876).
Настоящий документ описывает стандарт SHA1.
Описание реализации алгоритма SHA1 на языке C++:
typedef int HASH[5]; | |||
typedef int T512[16]; | |||
typedef int T80[80]; | |||
typedef int (*LPFNHASH)(int, int, int);// Функции F1, F2, F3 | |||
const int K1 = 0x5a827999; | |||
const int K2 = 0x6ed9ebal; | |||
const int КЗ = 0x8flbbcdc; | |||
const int K4 = 0xca62cld6; | |||
unsigned ROL (unsigned a, size_t s) | |||
{ | |||
return a << s | (a >> (sizeof (T)*8 - s)); | |||
} | |||
int f1 (int x, int y, int z) | |||
{ | |||
return x&y | (~x) &z; | |||
} | |||
int f2 (int x, int y, int z) | |||
{ | |||
return х^у^z; | |||
} | |||
int f3 (int x, int y, int z) | |||
{ | |||
return x&y | x&z | y&z; | |||
} | |||
void FillT80(T512 M, T80 W) | |||
{ | |||
size_t t; | |||
for (t = 0; t < 16; t++) W[t] = M[t]; | |||
for (; t < 80; t++) W[t] = ROL (W [t-3]^W [t-8]^W [t-14]^W [t-16], 1); | |||
} | |||
void MainStep (T80 W, size_t t, HASH H, LPFNHASH f, int K) | |||
{ | |||
int tmp = ROL (H[0], 5) + f (H [1], H [2], H [3]) + H [4] + W [t] + K; | |||
H [4] = H [3]; | |||
H [3] = H [2]; | |||
H [2] = ROL (H[1], 30) ; | |||
H [ 1 ] = H [ 0 ] ; | |||
H [0] = tmp; | |||
} | |||
void StepSHA (T512 M, HASH Hr) | |||
{ | |||
T80 W; | |||
FillT80 (M, W); | |||
size_t t; | |||
HASH H; | |||
memcpy (H, Hr, sizeof (HASH)); | |||
for (t = 0; t < 20; t++) MainStep (W, t, H, f1, K1); | |||
for (; t < 40; t++) MainStep (W, t, H, f2, K2); | |||
for (; t < 60; t++) MainStep (W, t, H, f3, К3); | |||
for (; t < 80; t++) MainStep (W, t, H, f2, K4); | |||
for (size_t i = 0; i < 5; i++) | |||
Hr[i] += H[i]; | |||
} |
Функции F1, F2, F3:
F1 (X,Y,Z) = (X Y) ((X) Z)
F2 (X,Y,Z) = X Y Z
F3 (X,Y,Z) = (X Y) (X Z) (Y Z)
ROL (X, Y) - циклический сдвиг X влево на Y разрядов;
где
- логическое "И";
- логическое "Или";
- логическое "Не";