Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.041 c
9-1111645986
ninja
2005-03-24 09:33
2005.06.29
интерфейс пользователя в игре


11-1086540713
Deimos
2004-06-06 20:51
2005.06.29
Linux


3-1116718926
grol
2005-05-22 03:42
2005.06.29
Как из ADOQuery ков перенести информацию в Excel?


4-1114536610
clampo
2005-04-26 21:30
2005.06.29
Инфа про WinAPI


1-1118235039
elena_
2005-06-08 16:50
2005.06.29
Как в при вызове Popmenu получить имя компнента вызвавшего его





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский