Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.99/130: Рейтинг темы: голосов - 130, средняя оценка - 4.99
Добрый самаритянин
1107 / 622 / 139
Регистрация: 31.03.2009
Сообщений: 2,567
1

TFileStream

23.02.2010, 20:46. Показов 24701. Ответов 26
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Delphi
1
2
3
4
5
6
7
8
9
var
Buff:array of char;
....
Stream:=TFilestream.Create('C:\4.fb2',fmOpenRead);
stream.Seek(0,soFromBeginning);
setlength(buff,i);//i-размер файла
stream.Read(buff,i);
memo1.Text:=strpas(buff); //тут ошибка вылетает. Так как записать содержимое из buff в переменную 
//типа стринг если массив динам???
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.02.2010, 20:46
Ответы с готовыми решениями:

TfileStream
Добрый день, Нужна помощь (весь нет облазил ничего не нашел). Объясните или скиньте литературу...

Ошибка в TFileStream
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics,...

что с TFileStream
что творится с TFileStream? Записываю переменную s:= '12345' типа string: S:='12345' ...

Работа с TFileStream
Объясните, как именно работать с данными,которые загружаю в поток. Например загружаю файл состоящий...

26
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
24.02.2010, 07:56 2
Чтение данных из файла должно быть выполнено так: stream.Read(Pointer(Buff)^, i);
Аргументом StrPas должены быть данные типа PChar. Если написать так:
Memo1.Text := StrPas(PChar(Buff));
Тогда StrPas станет просматривать массив buff до тех пор, пока не встретит терминальный ноль - это символ с кодом = 0. Таким образом, если в Buff имеется терминальный ноль, то строка будет обрезана на позиции, где он расположен. - Т. е. произойдёт потеря части строки, если терминальный ноль не в конце Buff. Если же терминального нуля вообще нет в Buff, тогда StrPas продолжит обработку байтов за пределами Buff - это скорее всего вызовет ошибку Access Violation, либо добавит в конец строки "мусор".
Поэтому придётся работать со строковым буфером. - Или стразу грузить в него данные из файла, или же копировать в него данные на этапе передачи данных в Мемо:
Delphi
1
2
3
4
5
6
7
8
9
10
var
  StrBuff : String;
...
begin
...
  SetLength(StrBuff, i);
  //Копирование данных из массива в строку.
  Move(Pointer(Buff)^, Pointer(StrBuff)^, Length(StrBuff));
  Memo1.Text := StrBuff;
...
Если есть уверенность, что в данных файла нет символов с кодом = 0, тогда можно проще поступить:
Delphi
1
2
3
4
5
6
7
8
9
10
11
var
Buff:array of char;
....
Stream:=TFilestream.Create('C:\4.fb2',fmOpenRead);
stream.Seek(0,soFromBeginning);
//i + 1 - предусматриваем дополнительный байт в конце - в него мы запишем терминальный ноль.
setlength(buff,i + 1);//i-размер файла
stream.Read(Pointer(Buff)^, i);
//Добавляем в конец буфера терминальный ноль.
Buff[i] := 0;
memo1.Text:=strpas( PChar(Buff) );
1
Добрый самаритянин
1107 / 622 / 139
Регистрация: 31.03.2009
Сообщений: 2,567
24.02.2010, 18:01  [ТС] 3
Да Mawrat, спасибо за такой подробный ответ
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
25.03.2011, 08:17 4
Здравствуйте, у меня аналогичная проблема...
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
var
  i, n, e: Integer;
  F:TFileStream;
  buf: string;
begin
  Memo1.Lines.Clear;
  F:=TFileStream.Create('1.txt',fmOpenRead);
  F.Seek(0,soFromBeginning);
  SetLength(buf,i);
  F.Read(buf,i);
  Move(Pointer(buf)^, Pointer(buf)^, Length(buf));
  Memo1.Text := buf;
  F.Free;
Но это не работает, в чем моя ошибка подскажите пожалуйста

Добавлено через 24 минуты
Вот по невнимательности упустил...
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
var
  i, n, e: Integer;
  F:TFileStream;
  buf: string;
  buff:array of char;
begin
  Memo1.Lines.Clear;
  F:=TFileStream.Create('1.txt',fmOpenRead);
  F.Seek(0,soFromBeginning);
  SetLength(buff,i);
  F.Read(buff,i);
  SetLength(buf,i);
  Move(Pointer(buff)^, Pointer(buf)^, Length(buf));
  Memo1.Text := buf;
  F.Free;
...
Но всё равно что не так...
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
25.03.2011, 09:06 5
Если надо загрузить данные именно в Мемо - эта задача решается в пару строк:
Delphi
1
2
3
4
5
6
7
8
const
  Fn = '1.txt';
var
  FileName : String;
begin
  FileName := ExtractFilePath( Application.ExeName ) + Fn;
  Memo1.Lines.LoadFromFile(FileName);
end;
Если надо загрузить содержимое файла в буфер - здесь требуется бОльший код. Вот различные способы загрузки в Мемо и в буфер:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//Загрузка содержимого файла в Мемо. Способ 1.
procedure TForm1.Button1Click(Sender: TObject);
const
  Fn = '1.txt';
var
  FileName : String;
begin
  FileName := ExtractFilePath( Application.ExeName ) + Fn;
  Memo1.Lines.LoadFromFile(FileName);
end;
 
//Загрузка содержимого файла в Мемо. Способ 2.
procedure TForm1.Button2Click(Sender: TObject);
const
  Fn = '1.txt';
var
  F : TFileStream;
  FileName : String;
begin
  //Полный путь к файлу.
  FileName := ExtractFilePath( Application.ExeName ) + Fn;
  try
    F := TFileStream.Create(FileName, fmOpenRead);
    F.Seek(0,soFromBeginning);
    Memo1.Lines.LoadFromStream(F);
  finally
    F.Free;
  end;
end;
 
//Загрузка содержимого файла в Мемо. Способ 3.
procedure TForm1.Button3Click(Sender: TObject);
const
  Fn = '1.txt';
var
  i : Integer;
  F : TextFile;
  FileName, buf : String;
begin
  Memo1.Clear;
  FileName := ExtractFilePath( Application.ExeName ) + Fn;
  AssignFile(F, FileName);
  try
    Reset(F);
    i := 0;
    while not Eof(F) do begin
      Read(F, Buf);
      if i = 0 then begin
        Inc(i);
        Memo1.Text := Buf;
      end else begin
        Memo1.Lines.Add(Buf);
      end;
      if Eoln(F) and (not Eof(F)) then Readln(F);
    end;
  finally
    CloseFile(F);
  end;
end;
 
//Неточная загрузка содержимого файла в Мемо. Если в файле нет завершающей
//пустой строки, то в Мемо она всё же будет присутствовать.
procedure TForm1.Button4Click(Sender: TObject);
const
  Fn = '1.txt';
var
  F : TextFile;
  FileName, buf : String;
begin
  Memo1.Clear;
  FileName := ExtractFilePath( Application.ExeName ) + Fn;
  AssignFile(F, FileName);
  try
    Reset(F);
    while not Eof(F) do begin
      Readln(F, Buf);
      Memo1.Lines.Add(Buf);
    end;
  finally
    CloseFile(F);
  end;
end;
 
//Загрузка содержимого файла в буфер. Способ 1.
procedure TForm1.Button5Click(Sender: TObject);
const
  Fn = '1.txt';
var
  i : Integer;
  F : TFileStream;
  FileName, buf : String;
begin
  //Полный путь к файлу.
  FileName := ExtractFilePath( Application.ExeName ) + Fn;
  try
    F:=TFileStream.Create(FileName, fmOpenRead);
    F.Seek(0,soFromBeginning);
    //Размер файла в байтах.
    i := F.Size;
    SetLength(buf, i);
    F.Read(Pointer(buf)^,i);
  finally
    F.Free;
  end;
  Memo1.Text := buf;
end;
 
//Загрузка содержимого файла в буфер. Способ 2.
procedure TForm1.Button6Click(Sender: TObject);
const
  Fn = '1.txt';
var
  i : Integer;
  F : File;
  FileName, buf : String;
begin
  FileName := ExtractFilePath( Application.ExeName ) + Fn;
  AssignFile(F, FileName);
  try
    //Открываем файл в режиме оперирования блоками размером в 1 байт.
    Reset(F, 1);
    //Размер файла в блоках. В нашем случае 1 блок = 1 байту.
    //Поэтому FileSize() вернёт размер файла в байтах.
    i := FileSize(F);
    SetLength(buf, i);
    BlockRead(F, Pointer(buf)^, i);
  finally
    CloseFile(F);
  end;
  Memo1.Text := buf;
end;
---
kovalevcon, эта строка не нужна:
Delphi
1
  Move(Pointer(buf)^, Pointer(buf)^, Length(buf));
Move - это процедура для копирования байтов в памяти.
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
25.03.2011, 09:40 6
Вроде работает но не как надо... поясню, с самого начала.
Смысл всего этого, что мне нужно применить шифрование RSA на файле (желательно чтоб можно было использовать любые расширения, а не только *.txt). Так вот программу для шифрования и дешифрования я нашел и хочу адаптировать для своих целей. Вот только где я не смотрел все программы работают с текстом, и только с ним, осуществляют преобразования над ним. Так вот я и подумал а если данные из файла представить в виде текста (String) сделать над ними шифрование и снова записать в файл. Возможно ли вообще такое сделать?Не изменяться ли данные файла после расшифровывания?
Я пробовал на файле *.rar, менял в ручную расширения на *.txt и получалось следующее содержимое:
Rar! О™sЂ
\+…^,юВ*тБѕЇРщ@э™ UнЌ@ѓ*hжяҐЄЂ¬д+`7ЊэHсLWҐ,†tЈП
ц§B™в6QA
5ТН?ўЦЪЇђ¤_CQнІюfrВЉH<˜cўх‰(?tЎх#л†:xъяьBw>pН@:ОlшДі„yТVуМ*«\+…^,юВ* aЇЬ‘рђlk7гx“*40p

А программа считывает данные только вот эту часть:
Rar!
Тот же результат если я не меняю расширения на txt или указываю как положено "1.rar".
...Вот я сижу и думаю не ужели делать все преобразования только на txt файле?
Жду вашего совета
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
25.03.2011, 10:17 7
От расширения файла его содержимое никак не поменяется. Что касается строки String (в Delphi7 String = AnsiString) - она используется как контейнер данных (байтов). Строка AnsiString - это последовательность байтов и в неё можно грузить любые данные, не важно что это - текст, изображение, звук или ещё что-то. К байтам можно применить механизм RSA шифрования так же как и к символам - это одно и тоже по сути.
Символ Char (AnsiChar) совпадает по внутреннему формату с типом Byte. Т. е. может принимать значения: 0..255. В терминах типа Char: #0..#255.
Поэтому, данные из файла можно грузить в String, array of Char или в array of Byte. Затем, к байтам применить процедуру шифрования.
Цитата Сообщение от kovalevcon Посмотреть сообщение
А программа считывает данные только вот эту часть:
Rar!
kovalevcon, ты пытаешься содержимое из *.rar загрузить в Мемо? Дело в том, что визуальные компоненты, отображающие текст, работают со строками типа PChar. В строках типа PChar окончания кодируются символом #0 - терминальный ноль называется. Т. е., это байт со значением = 0. Соответственно, если в такой строке встретится символ с кодом #0, то будет воспринята только та часть строки, которая идёт до кода #0. Всё что расположено правее #0 будет отсечено.
Например, выполним вот этот код:
Delphi
1
2
3
4
5
6
var
  S : String;
begin
  S := '012345' + #0 + '6789';
  Memo1.Text := S;
end;
В результате в Мемо будет показана только часть '012345'. По этой причине, при загрузке двоичных данных, в Мемо попадёт только та часть, которая идёт от начала файла до первого встретившегося терминального нуля (#0).
---
Вывод такой:
-В качестве буфера, принимающего данные из файла, может быть использованы переменные, например, следующих типов:
String, array of Char, array of Byte.
- Загружать данные в эти контейнеры можно из любых файлов.
- К загруженным байтам можно применять алгоритмы шифрования.
- Визуальные компоненты, применяемые для отображения текстовых данных, не подходят для показа двоичных данных, которые могут содержать нулевые байты.
1
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
25.03.2011, 11:11 8
Спасибо большое за разъяснение Я до этого заметил что что не так, взял и убрал через редактор один пробел (видать это и было #0) и всё за работало, но если чуть изменить файл он не будет исходным в конце после расшифровывания. Теперь шифрование надо реализовать в своей программе. Ещё раз большое спасибо!!!Отпишу когда всё заработает

---
Mawrat: Пожалуйста.
0
32 / 32 / 3
Регистрация: 04.04.2010
Сообщений: 414
25.03.2011, 11:26 9
А что вы за программы пишите, что такие проблемы? Просто делать нечего, афтер эффект надоел. Хочу чем нибудь позезным заняться.
0
Фрилансер
Эксперт С++
5845 / 1226 / 499
Регистрация: 23.11.2010
Сообщений: 3,375
Записей в блоге: 1
25.03.2011, 14:35 10
Цитата Сообщение от gore-lykovoe Посмотреть сообщение
Хочу чем нибудь позезным заняться.
Тогда перестань флудить
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
28.03.2011, 16:28 11
Здравия всем) Пишу опять по тому же поводу... теперь ситуация такая:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
type
  TIncodeMes = array of Integer;
...
private
    { Private declarations }
    FMes: TIncodeMes;
....
procedure TForm1.Button7Click(Sender: TObject);
var
s,buf: string;
Enc,Dec : TFileStream;
FileName, buff : String;
i,n,e: Integer;
 
begin
{ if OpenDialog2.Execute then
   s:=OpenDialog1.FileName;    } // Тут бы я хотел реализовать открытие файла через проводника
  try
    Enc:=TFileStream.Create('123.txt', fmOpenRead);
    Enc.Seek(0,soFromBeginning);
    i := Enc.Size;
    SetLength(buff, i);
    Enc.Read(Pointer(buff)^,i);
  finally
    Enc.Free;
   end;
  n := StrToIntDef(Edit4.Text,0); // Число n необходимое для шифрования 
  e := StrToIntDef(Edit5.Text,0); // Число e необходимое для шифрования 
  FMes := Encrypt(buff, e, n);
 
   try
    Dec:=TFileStream.Create('Dec.txt', fmOpenWrite);
    Dec.Seek(0,soFromBeginning);
    i := Dec.Size;
    SetLength(buff, i);
    Dec.Write(Pointer(FMes)^,i);
  finally
    Dec.Free;
  end;
Вот здесь реализуется открытие файла, считывание, шифрование и запись в файл... но видать из за функции шифрования, у меня не получается записать новые данные в файл.
Вот функция шифрования:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Функция быcтрого возведения в степень
function FastPower(a, b, n: integer): integer;
var i: integer;
    ai: extended;
begin
  ai := a;
  for I := Trunc(log2(b)) - 1 downto 0 do
  if Bit(b, i) then ai := Round(sqr(ai) * a) mod n else ai := Round(sqr(ai)) mod n;
  result := Round(ai);
end;
 
function Encrypt(s: string; e, n: integer): TIncodeMes;
  var I: Integer;
begin
  SetLength(result, length(s));
  for I := 0 to Length(s) - 1 do
    result[i] := FastPower(ord(s[i + 1]), e, n)
end;
Прошу помогите разобраться, пожалуйста

Добавлено через 9 минут
Сначала выдавал ошибку ошибку что то не с совместимостью переменных или выхода за приделе памяти...но теперь выполняет и в файл ничего не записывает...
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
28.03.2011, 22:06 12
Надо вот этот участок подправить:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
   try
    Dec:=TFileStream.Create('Dec.txt', fmOpenWrite);
    Dec.Seek(0,soFromBeginning);
    //Если файл создаётся впервые, получим i = 0.
    i := Dec.Size;
    //Buff при записи не понадобится. И здесь выставляется для Buff нулевая длина.
    SetLength(buff, i);
    //Так как i = 0, то в файл ничего не будет записано.
    Dec.Write(Pointer(FMes)^,i);
  finally
    Dec.Free;
  end;
надо заменить на:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
   try
    Dec:=TFileStream.Create('Dec.txt', fmOpenWrite);
    Dec.Seek(0,soFromBeginning);
    //Количество байт, которые будут записаны в файл.
    i := Length(FMes) * SizeOf(Integer);
    //Запись данных массива в файл.
    Dec.Write(Pointer(FMes)^,i);
    //Переопределяем размер файла. Это надо на случай, если перед записью файл имел
    //больший размер, чем массив FMes.
    Dec.Size := i;
  finally
    Dec.Free;
  end;
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
29.03.2011, 09:27 13
Спасибо, работает...вот теперь обратное действие, не работает.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
buf: string;
Enc,Dec : TFileStream;
FileName, buff : String;
i,n,d: Integer;
 
begin
  try
    Dec:=TFileStream.Create('Dec.txt', fmOpenRead);
    Dec.Seek(0,soFromBeginning);
    //Количество байт, которые будут записаны в файл.
    i := Dec.Size;
    SetLength(FMes, i);
    //Запись данных массива в файл.
    Dec.Read(Pointer(FMes)^,i);
    //Переопределяем размер файла. Это надо на случай, если перед записью файл имел
    //больший размер, чем массив FMes.
   { Dec.Size := i;   }
  finally
    Dec.Free;
   end;
 
 
  n := StrToIntDef(Edit4.Text,0);
  d := StrToIntDef(Edit6.Text,0);
  buf := Decrypt(FMes, d, n);
 
   try
    Enc:=TFileStream.Create('Enc.txt', fmOpenRead);
    Enc.Seek(0,soFromBeginning);
    //Размер файла в байтах.
    i := Enc.Size;
    SetLength(buf, i);
    Enc.Read(Pointer(buf)^,i);
  finally
    Enc.Free;
  end;
Проверял по дебагером, он считывает данные из файла нормально, но как приходит до дешифрования, выполняет его, но ничего не записывает в переменную buf... где возможно проблема?
Мне не нравится что постоянно из одного вида переменных в другую (из string в массив integer,из массива integer в string), может ли это повлиять на саму информацию?Не изменится ли она?
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
29.03.2011, 12:31 14
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
begin
  try
    Dec:=TFileStream.Create('Dec.txt', fmOpenRead);
    Dec.Seek(0,soFromBeginning);
    //Количество байт, которые будут прочитаны из файла.
    i := Dec.Size;
    SetLength(FMes, i);
    //Чтение данных из файла в массив.
    Dec.Read(Pointer(FMes)^,i);
  finally
    Dec.Free;
  end;
  
  n := StrToIntDef(Edit4.Text,0);
  d := StrToIntDef(Edit6.Text,0);
  buf := Decrypt(FMes, d, n);
 
  try
    Enc:=TFileStream.Create('Enc.txt', fmOpenRead);
    Enc.Seek(0,soFromBeginning);
    //Размер раскодированных данных в байтах.
    i := Length(buf) * SizeOf(Char);
    //Запись раскодированных данных в файл.
    Enc.Write(Pointer(buf)^,i);
    //Уточнение размера файла.
    Enc.Size := i;
  finally
    Enc.Free;
  end;
Здесь ещё названия неверно подобраны. Decodе - раскодированные данные, Encode - закодированные данные. Соответственно, файл с раскодированными данными надо назвать Dec.txt, а с закодированными: Enc.txt. Так же надо поступить и с именами объектов.

---
Mawrat: код выше надо подправить так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
begin
  try
    Dec:=TFileStream.Create('Dec.txt', fmOpenRead);
    Dec.Seek(0,soFromBeginning);
    //Количество байт, которые будут прочитаны из файла.
    i := Dec.Size;
    
    //Заменить:
    //SetLength(FMes, i);
    //на:
    SetLength(FMes, i div SizeOf(Integer));
 
    //Чтение данных из файла в массив.
    Dec.Read(Pointer(FMes)^,i);
  finally
    Dec.Free;
  end;
...
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
29.03.2011, 16:06 15
Ну я сижу и разбираюсь....запись и чтение из файлов проходит правильно.
Делаю следующее, открываю файл в нём допустим текст "priveT", после шифрования он записывается как массив integer типа вот такого:
Delphi
1
2
Fmes: (91, 88, 56, 118, 33, 84) // массив integer, зашифрованный текст и файла 
buff: 'priveT' переменная, то что было с читано из файла
Но из за вот этой строчки (кстати нужной, а то часть данных вообще не записывается в файл):
Delphi
1
  i := Length(Fmes)*SizeOf(Integer);
К массиву добовляется нули:
Delphi
1
Fmes: (91, 88, 56, 118, 33, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
И после расшифровывания наш текс ('priveT') выглядит таким образом:
Delphi
1
buf: 'priveT'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
Конечно в обычно текстовом редакторе '#0' не видно, они как обычные пробелы.
Я пытался обрезать эту переменную:
Delphi
1
2
j:= Length (buf);
Delete(buf,Pos('#0',buf),j);
Но она не обрезается, какие идеи будут по этому поводу?
Большое спасибо за предыдущие советы Если бы не они я бы долго ещё разбирался
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
29.03.2011, 16:31 16
Цитата Сообщение от kovalevcon Посмотреть сообщение
И после расшифровывания наш текс ('priveT') выглядит таким образом:
buf: 'priveT'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
Это значит, размер строки и/или массива неверно задаётся.
Delphi
1
i := Length(Fmes)*SizeOf(Integer);
Здесь i - это не количество элементов массива, а именно размер данных массива в байтах. Количество элементов массива будет в 4 раза меньше размера данных массива. Где-то в коде вместо длины строки или массива используется значение размера данных массива. - Из-за этого возникает лишняя длина.
kovalevcon, покажи как функция Decrypt() реализована. - Это она возвращает строку с неверной длиной.
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
29.03.2011, 16:37 17
Вот все исходники, я проверял шифрование на других типах файлов, кроме *.txt но при дешифровании выходит ошибка, такое чувство что где переменная выходит за свои пределы...
Вложения
Тип файла: rar RSA.rar (173.8 Кб, 19 просмотров)
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
29.03.2011, 16:51 18
kovalevcon, вот где проблема:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
procedure TForm1.Button2Click(Sender: TObject);
var
buf: string;
Enc,Dec : TFileStream;
FileName, buff : String;
i,n,d,j: Integer;
 
begin
if not OpenDialog1.Execute then Filename:= 'Dec.txt'
else
Filename:= OpenDialog1.Filename;
  try
    Dec:=TFileStream.Create(Filename, fmOpenRead);
    Dec.Seek(0,soFromBeginning);
    //Количество байт, которые будут записаны в файл.
    i := Dec.Size;
    
    //Заменить:
    //SetLength(FMes, i);
    //на:
    SetLength(FMes, i div SizeOf(Integer));
    
    //Запись данных массива в файл.
    Dec.Read(Pointer(FMes)^,i);
    {Dec.Read(FMes,i); }
    //Переопределяем размер файла. Это надо на случай, если перед записью файл имел
    //больший размер, чем массив FMes.
   { Dec.Size := i;   }
  finally
    Dec.Free;
   end;
...
Я пометил в коде, что надо заменить:
Delphi
1
2
3
4
    //Заменить:
    //SetLength(FMes, i);
    //на:
    SetLength(FMes, i div SizeOf(Integer));
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
30.03.2011, 12:52 19
Да верно это выход, только вот кое что забыли...
Если не добавить одну строчку:
Delphi
1
i:= i div SizeOf(Integer);
Во время записи дешифрованного сообщения в файл, то заместо 'priveT' будет следующее:
Delphi
1
buf: 'priveT'#0#0'ents and Setting'
Ну вот в принципе куда и добавлять:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  n := StrToIntDef(Edit4.Text,0);
  d := StrToIntDef(Edit6.Text,0);
  buf := Decrypt(FMes, d, n);
 
if not SaveDialog1.Execute then Filename:= 'Enc.txt'
  else
    begin
      Filename:= SaveDialog1.Filename;
      Dec:=TFileStream.Create(Filename, fmCreate);
      Dec.Free;
    end;
 
   try
    Enc:=TFileStream.Create(Filename, fmOpenWrite);
    Enc.Seek(0,soFromBeginning);
    i:= i div SizeOf(Integer);
    SetLength(buf, i);
    Enc.Write(Pointer(buf)^,i);
  finally
    Enc.Free;
  end;
Вроде теперь всё правильно...
Но при тестировании видно следующее (см. Пример.jpg)
Хотя если подобрать другой открытый и закрытый ключ все может быть верным...и опять эта проблема из за '#0','#1','#2','#3' (buf: 'q'#0'ert'#2'uiop[]asdfghjkl;''#3#1'cvbnm,./')
0
0 / 0 / 0
Регистрация: 20.02.2010
Сообщений: 15
30.03.2011, 12:53 20
Пример.jpg
Миниатюры
TFileStream  
0
30.03.2011, 12:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.03.2011, 12:53
Помогаю со студенческими работами здесь

Потоки (TFileStream)
Всем привет. Я решил узнать что такое потоки и т.п. Полазил по инету и научился открывать и...

Ошибка чтения из TFileStream
Следующий кусок кода не работает. Опыта работы с потоками не хватает разобраться почему. ...

TfileStream чтение данных
Начал работать с файловым потоком tfilestream, пытаюсь делать запись и чтение, с записью проблем...

Обработка исключений TFileStream
Подскажите, как при открытии файла через TFileStream.Create сделать исключение: если этот файл...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru