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

Вниз

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

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

Наверх




Память: 0.56 MB
Время: 0.011 c
2-1150358385
Crazy manager
2006-06-15 11:59
2006.07.02
Как узнать номер месяца


15-1149272356
homm
2006-06-02 22:19
2006.07.02
Кто виноват? Что делать?


2-1150095349
Sasha:)
2006-06-12 10:55
2006.07.02
ПОМОГИТЕ!


2-1150294685
Megabyte
2006-06-14 18:18
2006.07.02
Как "урезать" лишние знаки после запятой у чисел типа real?


5-1134742514
De
2005-12-16 17:15
2006.07.02
Хочу таскать панели, но как?





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