Главная страница
    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.044 c
9-1110528883
Guest2005
2005-03-11 11:14
2005.06.29
Вывод изображения используя средства D3D


3-1116306936
GydruS
2005-05-17 09:15
2005.06.29
Уважаемые мастера, почему падает БД Paradax с сообщением "Corr...


3-1116325991
OX
2005-05-17 14:33
2005.06.29
Из dBase в MS SQL и обратно


1-1117781895
qyu
2005-06-03 10:58
2005.06.29
Как в Grid


14-1117606571
NightStranger
2005-06-01 10:16
2005.06.29
Следующий вопрос на засыпку





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский