Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.29;
Скачать: CL | DM;

Вниз

TMemoryStream to hex string   Найти похожие ветки 

 
Yolly   (2005-06-07 10:51) [0]

Как можно оптимально перевести каждый байт 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!


 
TUser ©   (2005-06-07 10:52) [1]

> Этот метод меня не устраивает

Чем?


 
Polevi ©   (2005-06-07 11:00) [2]

function MemoryStreamToHexStr(AStream:TMemoryStream):string;
var
 i:integer;
begin
 Result:="";
 for i:=0 to AStream.Size-1 do
   Result:=Result+Format("%.2x ", [PByte(Integer(AStream.Memory)+i)^]);
end;


 
Yolly   (2005-06-07 11:37) [3]

Polevi ©   (07.06.05 11:00) [2]
это уже быстрее, спасибо !

но я думаю ту много времени теряется на изменение дины  Result Result:=Result+ ...

Если бы можно заранее определить размер Result а потом заполнить то получилось бы быстрее ?


 
Alexander Panov ©   (2005-06-07 11:42) [4]

Yolly   (07.06.05 10:51)
Метод очень неоптимален.


function StreamToHexStr(AStream: TStream): string;
const HexArr="0123456789ABCDEF";
var
 AByte: Byte;
 i: Integer;
begin
  SetLength(Result,AStream.Size*2);
  AStream.Position := 0;
  for i := 0 to AStream.Size-1 do
  begin
    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 12:25) [5]

индекс HexArr тут начинается с 1.
переделал так:

function StreamToHexStr(AStream: TStream): string;
const
//  HexArr = "0123456789ABCDEF";
 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
   AStream.ReadBuffer(AByte, SizeOf(AByte));
   Result[i * 2 + 1] := HexArr[AByte shr 4];
   Result[i * 2 + 2] := HexArr[AByte and $0F];
 end;
end;

так вроде работает.

Александр, это получается самый оптимальный метод?


 
Alexander Panov ©   (2005-06-07 12:56) [6]

Yolly   (07.06.05 12:25) [5]
Александр, это получается самый оптимальный метод?


Нет, не самый оптимальный.
Быстрее будет буфер из TStream читать блоками, и обрабатывать в цикле.
Мне так кажется.


 
Polevi ©   (2005-06-07 12:59) [7]

быстрее будет [5]+[2]


 
Alexander Panov ©   (2005-06-07 13:02) [8]

Polevi ©   (07.06.05 12:59) [7]
быстрее будет [5]+[2]


Это точно, если отступить от универсализма и использовать только TMemoryStream.


 
Yolly   (2005-06-07 13:05) [9]

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.


 
Yolly   (2005-06-07 13:10) [10]

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;


 
Polevi ©   (2005-06-07 13:12) [11]

Result[i * 2 + 1] := HexArr[AByte div 16];
Result[i * 2 + 2] := HexArr[AByte mod 16];
так понятнее ?


 
Yolly   (2005-06-07 13:13) [12]

Прошу прощения:

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:13) [13]

>Yolly   (07.06.05 13:10) [10]
ReadBuffer убери


 
Digitman ©   (2005-06-07 13:16) [14]


> AByte := PByte(Integer(AStream.Memory) + i)^;


мы легких путей не ищем ?)

AByte := PByteArray(AStream.Memory)[i];


 
Polevi ©   (2005-06-07 13:17) [15]

>Digitman ©   (07.06.05 13:16) [14]
насочиняют типов, всех и не упомнишь :-)


 
Yolly   (2005-06-07 13:39) [16]

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

Как это поучилось я понимаю. Но сам принцип - нет.


 
Digitman ©   (2005-06-07 13:46) [17]

как это так : как получилось понимаю, а принцип не понимаю ?

так не бывает)...

77 div 16 = 4 //получаем значение старшего ниббла байта (HiNibble)
77 mod 16 = 13//получаем значение младшего ниббла байта (LoNibble)

HexArr[4] = 4 //из эл-та массива с индексом HiNibble получаем соответствующий hex-символ
HexArr[13] = D //из эл-та массива с индексом LoNibble получаем соответствующий hex-символ


 
Alexander Panov ©   (2005-06-07 13:52) [18]

Байт состоит из 2-х полубайт, которые по-отдельности преобразуются в шестнадцатеричную цифру.
aByte: 77
Соответственно, старший полубайт содержит 0100, младший - 1101,
весь байт - 01001101
shr 4 - выполнение сдвига битов на 4 вправо.
соответственно
01001101 shr 4--> 00000100
AByte and $0F - обнуляет старший полубайт.

В каждом случае получаем индекс массива.


 
Polevi ©   (2005-06-07 14:00) [19]

да не грузите вы человека про полубайты, рано ему, тем более сдвиги и энды какието :)
пусть лучше про системы счисления почитает


 
Yolly   (2005-06-07 14:01) [20]

Digitman ©   (07.06.05 13:46) [17]
Не понимаю почему в результате деления (без остатка - div) байта на 16 получается индекс из масива HexArr, символ по этому индексу это есть первый символ для hex обозначения. То же самое для mod.

>>получаем значение старшего ниббла байта (HiNibble)
извиняюсь, но полностью не понимаю смысл фразы, прошу просветить.
что значит старший ниббл байт?


 
Yolly   (2005-06-07 14:03) [21]

Alexander Panov ©   (07.06.05 13:52) [18]
не успел прочитать.

Большое спасибо! Кое что начинается прояснятся в моей голове.


 
Yolly   (2005-06-07 14:09) [22]

Alexander Panov ©   (07.06.05 13:52) [18]

не понял только это
>>В каждом случае получаем индекс массива.

не понимаю как индекс масива HexArr связан с значениями этих 2 полубайт.


 
Digitman ©   (2005-06-07 14:11) [23]


> Yolly   (07.06.05 14:01) [20]


ниббл - это полубайт.

операция div 16 в дан.случае эквив-на shr 4 - сдвигу двоич.значения байта вправо на 4 двоич.разряда для получения значения старшего полубайта

операция mod 16 в дан.случае эквив-на and $0F - наложению маски
на 4 младших двоич.разряда значения байта для получения значения его мл.полубайта


 
Yolly   (2005-06-07 14:17) [24]

Digitman ©   (07.06.05 14:11) [23]
Спасибо ! понял.

мне осталось выяснить как значение этих 2 полубайт связанны с индексом массива HexArr.

Буду очень благодарен за разъяснение.


 
Polevi ©   (2005-06-07 14:22) [25]

http://comp-science.narod.ru/Progr/Syst_Sch.html



Страницы: 1 вся ветка

Текущий архив: 2005.06.29;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.028 c
4-1115364527
Colci
2005-05-06 11:28
2005.06.29
КАК Отключить интернет????


6-1111790626
Сеть
2005-03-26 01:43
2005.06.29
Подскажите способ простейшего обмена данными между двумя ip ? (


3-1116297685
weris
2005-05-17 06:41
2005.06.29
Запрос SQl - пробема ...


14-1117751148
Yegorchic
2005-06-03 02:25
2005.06.29
Болгария или Чехия?


4-1114721597
i-s-v
2005-04-29 00:53
2005.06.29
Постраничная организация памяти?