В результате анализа подсистемы защиты удалось выяснить, что подтверждение имени пользователя,работающего за компьютером, выполняется с помощью паролей. При проверке введенный пароль подвергается преобразованию при помощи функции,исходный код которой приведен ниже (см. табл.). Для принятия решения о том верен ли пароль, результат работы функции сверяется с эталонами, хранимыми в базе данных. Приведите пароль, который пройдет проверку описанную проверку, если известно, что пароль «БЕЗОПАСНОСТЬ» верен.
С |
Pascal |
int HASH(char *text) { int k=0, H; char temp[4]; for (int i=0; (i<strlen(text))&&(k<4); i++) if ((i+1)%2==0) {temp[k]=text[i]; k++;} if (k<4) for(;k<4;k++) temp[k]='D'; H = ((temp[0]+temp[3])&255)*256; H += (temp[1]+temp[2])&255; return H; } |
function HASH (text: string):Integer; var i, k, HA : Integer; temp: array [1..4] of char; begin k := 1; i := 1; while ((i <= Length (text)) and (k <= 4)) do begin if (i mod 2 = 0) then begin temp[k] := text[i]; k := k+1; end; i := i+1; end; if (k <= 4) then begin while k <= 4 do begin temp[k] := 'D';k := k+1; end; end; HA := ((ord(temp[1])+ord(temp[4])) and 255)*256; HA := HA + ((ord(temp[2])+ord(temp[3])) and 255); HASH := HA; end; |
Рассмотрим исходный код программы, написанный на языке C. Для удобства пронумеруем строки рассматриваемой функции:
int HASH(char *text) // 1
{
int k=0, H; // 2
char temp[4]; // 3
for (int i=0; (i
{
if ((i+1)%2==0) // 5
{
temp[k]=text[i]; k++; // 6
}
}
if (k<4) // 7
{
for(;k<4;k++) // 8
temp[k]='D'; // 9
}
H = ((temp[0]+temp[3])&255)*256; // 10
H += (temp[1]+temp[2])&255; // 11
return H; // 12
}
В программе использованы следующие переменные:
k – вспомогательная переменная;
temp– символьный массив из 4 элементов, используемый для хранения промежуточных данных при вычислениях;
H – целое число типа int (для хранениярезультата используются младшие два байта), предназначенное для хранения результирующего значения.
В цикле, реализованном в строках 4-6, происходит выборка символов из входной строки, стоящих на четных местах (номер позиции символа в строке считается с 1). Причем в цикле выбирается не более 4 символов. Таким образом, после выполнения этой части программа (с учетом того, что по условию задачи преобразуется пароль «БЕЗОПАСНОСТЬ») переменная tempбудет имеет заполнение«ЕОАН».
В строках7-9 происходит проверка на длину строки temp. Если полученная в результате работы предыдущего цикла строка меньше 4, то она дополняется символами «D». Это преобразование существенно при подборе пароля.
В строке с номером 10 начинает формироваться выходное значение. ASCII-коды первого и четвертого символов буфера tempскладываются (по модулю 256), а результата записывается в старший байт переменной H. В результате выполнения строки 11 младший байт переменной Hбудет содержать сумму кодов второго и третьего символовстроки temp (по модулю 256). Таким образом, после выполнения функции, в которой преобразуется пароль «БЕЗОПАСНОСТЬ», возвращаемый результат равен 3751810 = 10010010 100011102.
Для решения задачи необходимо предложить такой пароль, образ, которого полученный в результате работы функции будет равен 37518. Очевидно, что искомый пароль не может быть меньше четырех символов, в противном случае младший байт образа пароля будет равен 13610 = 100010002, а не 14210 = 100011102 как требуется.
Пусть пароль содержит 4 символа, обозначит второй символ как P1, а четвертый P2. Тогда после выполнения строк 7-9 дальнейшему преобразованию будет подвержена строка «P1P2DD». Зная результирующее значение и, используя строки 11 и 12 исходного кода функции, составим следующие уравнения: P1+68=146 (mod 256) и P2+68 = 142 (mod 256).
Таким образом, пароль *N*J (где * –любой символ) верен.