![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TMemoryStream to hex string [D7, WinXP]
Yolly © (2005-06-07 10:51:00)Как можно оптимально перевести каждый байт TMemoryStream в hex.
Сейчас делаю так :
function StreamToHexStr(AStream: TStream): string;
var
AByte: Byte;
begin
try
Result := '';
AStream.Position := 0;
while AStream.Position < AStream.Size do
begin
AStream.ReadBuffer(AByte, SizeOf(AByte));
Result := Result + Format('%.2x ', [AByte]);
end;
except
Result := '';
end
end;
Этот метод меня не устраивает но пока придумать другой
не могу. HELP!
Polevi (2005-06-07 14:22:00) [1]http://comp-science.narod.ru/Progr/Syst_Sch.html
Yolly (2005-06-07 14:17:00) [2]Digitman © (07.06.05 14:11) [23]
Спасибо ! понял.
мне осталось выяснить как значение этих 2 полубайт связанны с индексом массива HexArr.
Буду очень благодарен за разъяснение.
Digitman (2005-06-07 14:11:00) [3]
> Yolly (07.06.05 14:01) [20]
ниббл - это полубайт.
операция div 16 в дан.случае эквив-на shr 4 - сдвигу двоич.значения байта вправо на 4 двоич.разряда для получения значения старшего полубайта
операция mod 16 в дан.случае эквив-на and $0F - наложению маски
на 4 младших двоич.разряда значения байта для получения значения его мл.полубайта
Yolly (2005-06-07 14:09:00) [4]Alexander Panov © (07.06.05 13:52) [18]
не понял только это
>>В каждом случае получаем индекс массива.
не понимаю как индекс масива HexArr связан с значениями этих 2 полубайт.
Yolly (2005-06-07 14:03:00) [5]Alexander Panov © (07.06.05 13:52) [18]
не успел прочитать.
Большое спасибо! Кое что начинается прояснятся в моей голове.
Yolly (2005-06-07 14:01:00) [6]Digitman © (07.06.05 13:46) [17]
Не понимаю почему в результате деления (без остатка - div) байта на 16 получается индекс из масива HexArr, символ по этому индексу это есть первый символ для hex обозначения. То же самое для mod.
>>получаем значение старшего ниббла байта (HiNibble)
извиняюсь, но полностью не понимаю смысл фразы, прошу просветить.
что значит старший ниббл байт?
Polevi (2005-06-07 14:00:00) [7]да не грузите вы человека про полубайты, рано ему, тем более сдвиги и энды какието :)
пусть лучше про системы счисления почитает
Alexander Panov (2005-06-07 13:52:00) [8]Байт состоит из 2-х полубайт, которые по-отдельности преобразуются в шестнадцатеричную цифру.
aByte: 77
Соответственно, старший полубайт содержит 0100, младший - 1101,
весь байт - 01001101
shr 4 - выполнение сдвига битов на 4 вправо.
соответственно
01001101 shr 4--> 00000100
AByte and $0F - обнуляет старший полубайт.
В каждом случае получаем индекс массива.
Digitman (2005-06-07 13:46:00) [9]как это так : как получилось понимаю, а принцип не понимаю ?
так не бывает)...
77 div 16 = 4 //получаем значение старшего ниббла байта (HiNibble)
77 mod 16 = 13//получаем значение младшего ниббла байта (LoNibble)
HexArr[4] = 4 //из эл-та массива с индексом HiNibble получаем соответствующий hex-символ
HexArr[13] = D //из эл-та массива с индексом LoNibble получаем соответствующий hex-символ
Yolly (2005-06-07 13:39:00) [10]Polevi © (07.06.05 13:12) [11]
Прошу простить за непонимание.
Например имеется AByte = 77.
В hex это будет 4D - вычислил это калькулятором.
и действительно
77 div 16 = 4
77 mod 16 = 13
HexArr[4] = 4
HexArr[13] = D
Как это поучилось я понимаю. Но сам принцип - нет.
Polevi (2005-06-07 13:17:00) [11]>Digitman © (07.06.05 13:16) [14]
насочиняют типов, всех и не упомнишь :-)
Digitman (2005-06-07 13:16:00) [12]
> AByte := PByte(Integer(AStream.Memory) + i)^;
мы легких путей не ищем ?)
AByte := PByteArray(AStream.Memory)[i];
Polevi (2005-06-07 13:13:00) [13]>Yolly (07.06.05 13:10) [10]
ReadBuffer убери
Yolly (2005-06-07 13:13:00) [14]Прошу прощения:
function MemoryStreamToHexStr(AStream: TMemoryStream): string;
const
HexArr: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F');
var
AByte: Byte;
i: Integer;
begin
SetLength(Result, AStream.Size * 2);
for i := 0 to AStream.Size - 1 do
begin
AByte := PByte(Integer(AStream.Memory) + i)^;
Result[i * 2 + 1] := HexArr[AByte shr 4];
Result[i * 2 + 2] := HexArr[AByte and $0F];
end;
end;
Polevi (2005-06-07 13:12:00) [15]Result[i * 2 + 1] := HexArr[AByte div 16];
Result[i * 2 + 2] := HexArr[AByte mod 16];
так понятнее ?
Yolly (2005-06-07 13:10:00) [16]Polevi © (07.06.05 12:59) [7]
Alexander Panov © (07.06.05 12:56) [6]
вот так ?
function MemoryStreamToHexStr(AStream: TMemoryStream): string;
const
HexArr: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F');
var
AByte: Byte;
i: Integer;
begin
SetLength(Result, AStream.Size * 2);
AStream.Position := 0;
for i := 0 to AStream.Size - 1 do
begin
AByte := PByte(Integer(AStream.Memory) + i)^;
AStream.ReadBuffer(AByte, SizeOf(AByte));
Result[i * 2 + 1] := HexArr[AByte shr 4];
Result[i * 2 + 2] := HexArr[AByte and $0F];
end;
end;
Yolly (2005-06-07 13:05:00) [17]Alexander Panov © (07.06.05 12:56) [6]
ОК. Спасибо.
Можете еще обяснить, если есть время, как в результате:
Result[i * 2 + 1] := HexArr[AByte shr 4];
Result[i * 2 + 2] := HexArr[AByte and $0F];
получается hex обозначение AByte.
Alexander Panov (2005-06-07 13:02:00) [18]Polevi © (07.06.05 12:59) [7]
быстрее будет [5]+[2]
Это точно, если отступить от универсализма и использовать только TMemoryStream.
Polevi (2005-06-07 12:59:00) [19]быстрее будет [5]+[2]
Alexander Panov (2005-06-07 12:56:00) [20]Yolly (07.06.05 12:25) [5]
Александр, это получается самый оптимальный метод?
Нет, не самый оптимальный.
Быстрее будет буфер из TStream читать блоками, и обрабатывать в цикле.
Мне так кажется.