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

Вниз

Задачка   Найти похожие ветки 

 
AlexanderMS ©   (2006-06-02 18:20) [0]

В файле записано число типа integer следующим образом. Если открыть файл с помощью шестнадцеричного редактора, то окажется, что число записано 4 байтами с шест. кодами соответственно

00 00 4С 98

Но это число имеет код "наоборотный", т. е.

98 4С 00 00

Это число 19608. Как его можно прочитать из файла с помощью TFileStream, если оно в таком зашифрованном виде?!


 
Desdechado ©   (2006-06-02 18:25) [1]

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


 
AlexanderMS ©   (2006-06-02 18:27) [2]

Кстати, это не просто задачка, это - моя проблема. Не могу придумать. В файле (опять из игры СnС Generals) почему-то 2 числа (начало файла в архиве и длина файла) записаны наоборот, видимо, для защиты. А я пишу редактор! Вот и не знаю. Пробовал через чтение Read переменной типа string и её reversestring, а как в Integer перевести - ?


 
AlexanderMS ©   (2006-06-02 18:28) [3]


> Desdechado ©   (02.06.06 18:25) [1]

И как быть?


 
MBo ©   (2006-06-02 18:39) [4]

>AlexanderMS
В [1] уже все сказано.

P.S. Непонятно, зачем читать строку, если там Integer


 
MBo ©   (2006-06-02 18:41) [5]

http://www.delphikingdom.ru/lyceum/
Разделы:
Начинающим программистам. Уроки Юрия Зотова.
Уроки от АП


 
AlexanderMS ©   (2006-06-02 18:44) [6]

Так там integer наоборот записан. Есть разница:
19608 и -1739849728, как читает FileStream!


 
Piter ©   (2006-06-02 18:47) [7]

procedure TForm1.Button1Click(Sender: TObject);
var
 i: LongWord;
 fs: TFileStream;
begin
 fs := TFileStream.Create("myfile", fmOpenRead);
 try
   fs.Position := 0;
   fs.WriteBuffer(i, 4);
   showmessage("Число: "+inttostr(i));
 finally
   fs.Free ;
 end;
end;


 
MBo ©   (2006-06-02 18:48) [8]

Есть одно тонкое место -

>как читает FileStream!
при твоем способе применения...


 
Cash ©   (2006-06-02 18:49) [9]

AlexanderMS ©   (02.06.06 18:27) [2]:
Тоже Генералов потрошим??? :)))
Я своих уже с год как раздербанил. :)))
Я там (ну типа "молодэ, зеленэ, як ж так можно то" :) ) запись использовал
с вариантами.
Type
  TLongInt = packed record
    case Word of
      0: (Value: LongInt);
      1: (Bytes: array [0..3] of byte);
  end;


Дошло? :)))

ЗЫ: просто читаем из стрима вперед, а в Bytes записываем с зада, а
потом берем Value! И усё!!! :)))


 
Piter ©   (2006-06-02 19:00) [10]

блин, автор запутал меня. Так как хранится число в файле?

00 00 4С 98 - вот так?

Так это и есть обычное представление HEX. Набери в виндовом калькуляторе в HEX режиме: 4C98 - и переведи в DEC, это и есть 19608


 
Cash ©   (2006-06-02 19:03) [11]

Число в стриме записано с обратным порядком байт!
Читать его надо тоже с зада на перед! :)
Но так как стрим с зада не почитаешь, приходится в тот самый ... писать! :)))
:)))


 
AlexanderMS ©   (2006-06-02 19:07) [12]

Спасибо за советы. Буду пробовать.


> Я своих уже с год как раздербанил. :)))

То есть?


 
Бормодед ©   (2006-06-02 19:08) [13]

function Convert(const Value: Integer): Integer;
asm
BSWAP EAX
end;


 
Piter ©   (2006-06-02 19:09) [14]

В моем примере можно тогда так:

procedure TForm1.Button1Click(Sender: TObject);
var
i: LongWord;
fs: TFileStream;
begin
fs := TFileStream.Create("myfile", fmOpenRead);
try
  fs.Position := 0;
  fs.WriteBuffer(i, 4);
  i := (i shl 24) + ( (i shl 8) and $00FF0000 ) + ( (i shr 8) and $0000FF00) + (i shr 24);
  showmessage("Число: "+inttostr(i));
finally
  fs.Free ;
end;
end;


 
AlexanderMS ©   (2006-06-02 19:09) [15]


> Так это и есть обычное представление HEX. Набери в виндовом
> калькуляторе в HEX режиме: 4C98 - и переведи в DEC, это
> и есть 19608


Это ладно, а число записано наоборот!


 
Piter ©   (2006-06-02 19:12) [16]

Бормодед ©   (02.06.06 19:08) [13]
function Convert(const Value: Integer): Integer;
asm
BSWAP EAX
end;


во, точно. Знание ассемблера рулез :)

Именно так и надо, а то я напридумывал:

i := (i shl 24) + ( (i shl 8) and $00FF0000 ) + ( (i shr 8) and $0000FF00) + (i shr 24);

:)))


 
Cash ©   (2006-06-02 19:13) [17]

AlexanderMS ©   (02.06.06 19:07) [12]:
Я распаковщик написал, раздербанил и успокоился. :)
И для чтения смещения и размера файла использовал эту запись и этот метод.


 
Cash ©   (2006-06-02 19:15) [18]

> function Convert(const Value: Integer): Integer;
> asm
> BSWAP EAX
> end;


А я в справочниеке его не нашел! Идать такого нет...


 
Piter ©   (2006-06-02 19:16) [19]

AlexanderMS ©   (02.06.06 19:09) [15]
Это ладно, а число записано наоборот!


как это наоборот?!

Записано: 00 00 4С 98 - ТАК?

Так вот: $00004C98 - это и есть: 19608

Как раз число записано соверщенно верно.

Проблема только в том, что в x86 процессорах числа как раз хранятся наоборот. Поэтому тебе и надо поменять байты, как сказал Бормодед ©   (02.06.06 19:08) [13]


 
Cash ©   (2006-06-02 19:19) [20]

Piter ©   (02.06.06 19:16) [19]:
Ух, елы-палы, я ж отписал уже - с обратным порядком байт, это значит:
$4C980000

А это уже другое чило!


 
Cash ©   (2006-06-02 19:20) [21]

Не, точнее будет: $984C0000


 
Piter ©   (2006-06-02 19:26) [22]

Cash ©   (02.06.06 19:19) [20]
Ух, елы-палы, я ж отписал уже - с обратным порядком байт, это значит:


что с обратным порядком байт е-мое?!?!?!?

В файле число записано как раз с нормальным порядком расположения байт!


 
Cash ©   (2006-06-02 19:45) [23]

Piter ©   (02.06.06 19:26) [22]
Look to [21].
В файле вместо $00004C98 записано $984C0000.


 
Cash ©   (2006-06-02 19:48) [24]

Piter ©   (02.06.06 19:26) [22]:
Ты Генералов рипал? ихние *.BIG файлы распаковывал?
Там в файле *.BIG FAT построена с обратным порядком байт.
Т. е. четырехбайтовые числа записаны наобарот.


 
default ©   (2006-06-02 19:49) [25]

никакого обращения байт не нужно
если теория хромает, можно экспериментом понять, наконец

procedure TForm1.Button1Click(Sender: TObject);
var
 dw: LongWord;
 f: File;
begin
 dw := $61626364;
 AssignFile(f, "C:/myfile.txt");
 Rewrite(f, 1);
 BlockWrite(f, dw, 4);
 Reset(f, 1);
 BlockRead(f, dw, 4);
 CloseFile(f);
 Caption := IntToHex(dw, 8);
end;


 
Cash ©   (2006-06-02 19:51) [26]

Уффф... молчу... молчу... слов моих больше нет!... :(


 
Piter ©   (2006-06-02 19:54) [27]

Cash ©   (02.06.06 19:45) [23]
В файле вместо $00004C98 записано $984C0000


ок. В файле записано: 984C0000

Смотрим на твой код в посте [9]:

после него в память компьютера будут занесены байты:

00 00 4C 98

А для x86 процессоров для беззнаковых чисел, это в десятичном представлении: 2555117568

То бишь, два с половиной с лихом миллиардов :)


 
Юрий Зотов ©   (2006-06-02 19:54) [28]

> AlexanderMS ©   (02.06.06 18:20)  

Все действительно сказано уже в [1]. Целые числа в памяти Intel хранятся в обратном порядке байт. То есть, если 4-х байтовая целая переменная I равна 19608, то в памяти, где она находится, мы увидим 98 4С 00 00.

Никаких преобразований тут не требуется, все происходит автоматически. Например:

var
 I: integer;
 P: PByte;
begin
  I := 19; // В памяти будет 03 01 00 00
  P := @I; // P указывает на первый в памяти байт I (равный 03).
  P^ := $98; // В памяти стало 98 01 00 00, I теперь равно 408 (DEC)
  Inc(P); // P указывает на второй в памяти байт I (равный 01).
  P^ := $4C; // // В памяти стало 98 4C 00 00, I теперь равно 19608 (DEC)
end;
 
В файл содержимое памяти записывается "как есть", и FileStream читает файл и пишет его в память тоже "как есть" - поэтому Вы и видите числа "в обратном порядке" (а на самом деле порядок тот, который нужен).

Преобразовывать ничего не требуется. Если известен адрес P в памяти, по которому хранится число, то получить значение этого числа очень просто:
I := PInteger(P)^;

И все, никаких преобразований.

PS
Немного странно, что человек, не знающий подобных вещей (а все изложенное - это всего лишь один из множества параграфов азбуки программирования), взялся что-то там ломать. Не рановато ли?


 
default ©   (2006-06-02 19:55) [29]

хотя пардон, нужно таки обратить:)


 
Piter ©   (2006-06-02 19:58) [30]

Юрий Зотов ©   (02.06.06 19:54) [28]

Юрий, да нет, вас тоже запутали. В файлах на диске как раз все хранится в правильном порядке. Поэтому при чтении в память байты надо переставлять.


 
begin...end ©   (2006-06-02 19:59) [31]

> Юрий Зотов ©   (02.06.06 19:54) [28]

> I := 19; // В памяти будет 03 01 00 00

Сомневаюсь...


 
Юрий Зотов ©   (2006-06-02 20:01) [32]

Так. Будем распутывать путаников.

Есть 4-байтовое число 15 ($0F). В памяти оно будет выглядеть так:
0F 00 00 00

Как оно будет записано в вашем хитром файле?


 
Piter ©   (2006-06-02 20:05) [33]

Юрий Зотов ©   (02.06.06 20:01) [32]

вот. Аналогичный вопрос.
У него там число: 19608

Как оно будет храниться в ФАЙЛЕ, как:

00 00 4С 98

или как:

98 4С 00 00

Если первый вариант - то перестановку делать надо, но сам Cash утверждает, что там хранится второй вариант. А в этом случае пост [9] Cash"а вообще бред и ничего такого делать не надо. Но у него я так понимаю получился редактор?


 
default ©   (2006-06-02 20:06) [34]

есть число 19608=$00004С98
в файл запишется так: 984C0000    (1)
считается: 00004С98(что и писалось)  (2)
если же в файле лежит 00004С98(не (1)), то и считается не (2), а надо чтобы читалось (2)  

все штука в том что пишется;) а пишется 19608:)


 
Piter ©   (2006-06-02 20:07) [35]

begin...end ©   (02.06.06 19:59) [31]
> I := 19; // В памяти будет 03 01 00 00

Сомневаюсь...


ну очевидно в памяти будет: 13 00 00 00


 
Юрий Зотов ©   (2006-06-02 20:09) [36]

> begin...end ©   (02.06.06 19:59) [31]

259, конечно.


 
Cash ©   (2006-06-02 20:13) [37]

Ребят, вы просто запутались! Кто здесь рипал Генералов? Кто ни будь еще
занимался вскрытием форматов?

Мое мнение маленькое! Я только дал инфу, как ей распоряжаться думайте
сами. Думаю, автор так же как и я понимает, о чем идет речь. Думаю,
просто вы маленько запутались.

Неохота мне сейчас ставить Генералов, и выдирать от туда кусок HEX данных
на всеобщий показ.

ЗЫ: ... Хотя где то там была моя статейка... А... вот она... выложил на
короткий срок. Посмотрите. Пособие для сборки экстрактора из BIG формата.
http://www.codefusion.jino-net.ru/articles/bigform.htm


 
default ©   (2006-06-02 20:14) [38]

причина путаниц в том, какое число пишется в файл:)


 
Piter ©   (2006-06-02 20:16) [39]

Cash ©   (02.06.06 20:13) [37]

да ты между прочим больше всех и запутал :))
Ответь на элементарный вопрос. Вот есть число: 19608

Как оно будет хранится в файле на жестком диске? Порядок байт какой будет?
такой:

1) 00 00 4С 98

или такой:

2) 98 4С 00 00

просто ты утверждаешь, что порядок байт будет как в случае 2).

НО. При этом твой же пост [9] есть бред тогда.


 
default ©   (2006-06-02 20:20) [40]

"В файле вместо $00004C98 записано $984C0000."
под "в файле записано" он имеет ввиду число, а не последовательность байт:)
$984C0000-->00004C98(в файле)

бывает же! много шума из ничего!



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

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

Наверх




Память: 0.57 MB
Время: 0.038 c
15-1148979437
MsGuns
2006-05-30 12:57
2006.07.02
Администрирование SQL.


2-1150196083
dim2001
2006-06-13 14:54
2006.07.02
разделители триад


1-1148549206
D@Nger
2006-05-25 13:26
2006.07.02
Работа с считывателем пластиковых карт


15-1149660937
alex_drob
2006-06-07 10:15
2006.07.02
Софт для спутниковых ресиверов


15-1149282888
Tack
2006-06-03 01:14
2006.07.02
Нужна простенькая однопользовательская система контроля версий