Консультация № 187594
27.10.2013, 15:16
100.51 руб.
0 15 1
Здравствуйте,уважаемые эксперты.
Нужно написать программу,желательно используя MASM.
Даны две строки:
строка1 "F4D531675F637A9745967E883A7AB18E"
строка2 "0123456789ABCDEFGHJKLMNPQRTUVWXY"

Строку1 нужно разбить на 16 двухбайтных слов и с каждым из слов провести логическую операцию И (AND) c 8000001Fh,тут же прибавляя к
каждому из 16 получившихся значений единицу.Каждый получившийся р-тат-- это смещение в строке2,по которому нужно взять символ,и,когда их наберётся 16,в виде строки вывести на экран (в данном случае это "LMH7Y3TP5NX8TTHE").
Спасибо.

Обсуждение

давно
Посетитель
7438
7205
27.10.2013, 17:33
общий
Здравствуйте, Сергей!
Два вопроса:..
1) Работаем с 16-битными словами, почему в условии 32-битное число 8000001Fh? По идее, должно быть 001fh.
2) Зачем прибавлять единицу? Чтобы получить требуемый результат, ничего прибавлять не надо! Ведь получим число от 0 до 1fh, т.е. индекс в пределах от 0 до 31, как раз, чтобы получить значение из второй строки, которых ровно 32. Или индекс считается не с 0, а с 1?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.10.2013, 20:06
общий
27.10.2013, 20:20
Игорь Витальевич,Вы правы по пункту 1, а с пунктом 2--- похоже получается так,что отсчёт начинается с единицы.Так получается нужная буковка "L".
давно
Посетитель
7438
7205
27.10.2013, 20:29
общий
Это в обиходе считают, начиная с 1, а в программировании, в ассемблере, в частности, с 0

Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.10.2013, 20:41
общий
Без инкремента буковка L не получится)
давно
Посетитель
7438
7205
27.10.2013, 20:58
общий
27.10.2013, 21:18
Может, мы по-разному считаем
Я так: берем четыре hex-цифры F4D5, из которых получаем число 0d5f4h (младший байт получаем первым)
Операция And 001fh дает число-смещение 14h, по которому во второй строке и лежит буковка 'L'
Как Вы считаете?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
27.10.2013, 21:29
общий
Ну и? Аргументируйте:
Без инкремента буковка L не получится)
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.10.2013, 21:37
общий
27.10.2013, 22:03
Знания мои очень слабенькие пока что, и я запутался.Если брать F4D5 то получается всего 8 слов и соответственно 8 символов из строки2,а нужно 16. Их похоже нужно брать F4,D5,...и т.д Дело похоже в кодировке.F4 это 2 байта 4634h.
Запустил оригинал под отладчиком:
..............................
and ESI,8000001f
.............................
add ESI,1
.............................
в ESI лежит 15h
давно
Посетитель
7438
7205
27.10.2013, 22:07
общий
А это, смотря как брать
Можно и по два байта, но со смещением 1, т.е. f4d5, d531 и т.д.
Что по сути равно чтения двух hex-цифр :), т.е. f4,d5,31,...
Я просто исходил из условия "разбить на 16 двухбайтных слов"
Кодивка не проходит. Смотрим:
F4 = 4634h -> 14h -> L !
D5 = 4435h -> 15h ->M !
31 = 3331h -> 11h ->H !
67 = 3637h -> 17h ->P, а должно быть 07h -> 7 !
Предлагаю читать в младшее полуслово очередные две hex-цифры,
делать and 001fh и читать символ ил второй строки.
Тогда все получится
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
27.10.2013, 22:13
общий
в ESI лежит 15h
Разумеется, будет 15h = 14h + 1
Но по этому смещению во второй строке лежит не L, а М!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.10.2013, 22:14
общий
Игорь Витальевич,делайте как считаете нужным.Это и будет правильно .
давно
Посетитель
7438
7205
27.10.2013, 22:16
общий
И, кстати, зачем используем 32-битный регистр ESI? Вполне достаточно 16-битных.
Задачка-то под ДОС. Или все же под Windows?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.10.2013, 22:24
общий
27.10.2013, 22:29
Задачка под Windows. Первая часть задачи дописывает к введённому имени строковую константу и считает MD5 получившейся строки.С этим я сам как-то справился.А дальше не смог.Так что строка1--это MD5 хеш.
Так что то,что получу от Вас, разберу по кирпичикам,внимательно изучу, и сложу в одно целое с тем,что у меня уже есть.
давно
Посетитель
7438
7205
27.10.2013, 22:35
общий
Лады, сделаю, только, наверное, уже ночью Пока занят.
Позже, если понадобится, внесем коррекции...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
27.10.2013, 22:40
общий
28.10.2013, 07:10
Спасибо, всё работает
давно
Посетитель
7438
7205
28.10.2013, 01:38
общий
это ответ
Здравствуйте, Сергей!
Т.к. в данном примере число исходных данных ровно столько, сколько надо,
то проверка на 16 байт отсутствует. Это легко добавляется.
Демонстрируется сама идея обработки данных.
Примерно так:
[code h=200]
.386
.model flat, stdcall
option casemap :none

;подключаем необходимые inc-файлы
include \masm32\include\windows.inc
;include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

;и библиотеки
;includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

;прототипы функций
StdOut PROTO :DWORD, :DWORD
GetNibble PROTO
GetNum PROTO
CalcText PROTO :DWORD, :DWORD, :DWORD

;стек
.stack 1024

;сегмент данных
.data
sMD5 db "F4D531675F637A9745967E883A7AB18E"
lenMD5 equ ($-sMD5)/2 ;количество данных
sData db "0123456789ABCDEFGHJKLMNPQRTUVWXY"
sTitle db "Decoding text: "

.data?
sText db 256 dup (?)

;сегмент кода
.code
main proc
local hOutPut:DWORD ;описатель стандартного выходного устройства
;получаем handle устройства
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hOutPut, eax

;выводим "Decoding text: "
invoke StdOut, hOutPut, addr sTitle

invoke CalcText, addr sMD5, lenMD5, addr sText

;выведем строку
invoke StdOut, hOutPut, addr sText
;выход
invoke ExitProcess, NULL
main endp

GetNibble proc ;hex-символ в hex-число 0-f
lodsb
sub al, '0'
cmp al, 9 ;0-9 ?
jbe GetNibbleRet
sub al, 'A'-'0'-0ah ;A-F
GetNibbleRet:
ret
GetNibble endp

GetNum proc ;два hex-символа в байт
call GetNibble
shl al, 4
mov ah, al
call GetNibble
or al, ah
ret
GetNum endp

CalcText proc uses esi ecx edi, pMD5:DWORD, iCount:DWORD, pText:DWORD
mov esi, pMD5 ;адрес массива
mov ecx, iCount ;его длина
mov edi, pText
CalcTextLoop:
call GetNum
and eax, 0000001fh
mov al, sData[eax]
stosb
loop CalcTextLoop
mov byte ptr [edi], 0 ;закроем строку нулем для вывода
ret
CalcText endp

;вывод строки на стандартное выходное устройство
;параметр - адрес строки
StdOut proc hOutPut:DWORD, lpszText:DWORD
;локальные переменные в стеке
LOCAL bWritten:DWORD ;количество выведенных символов
LOCAL len:DWORD ;длина строки

;получаем длину строки
invoke lstrlen, lpszText
mov len, eax

;выводим
invoke WriteFile, hOutPut, lpszText, len, ADDR bWritten, NULL

;возвращаем количество выведенных символов
mov eax, bWritten
ret
StdOut endp

end main
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа