PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Получить русские символы из файла при раскодировке


Получить русские символы из файла при раскодировке

Сообщений 1 страница 19 из 19

1

Привет всем. Я, вероятно, не понимаю каких-то азов, но, уже все попробовал, надеюсь на помощь зала )

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

Код:
m$="d:\test.txt"
a$="ф"
Debug "исходнодн="+a$
  OpenFile(5, m$, #PB_UTF8 ) ; игры с #PB_UTF8/#PB_Unicode  и вообще без  не помогают
   b=Asc(a$) ! Asc("5") ;шифруем
   WriteByte(5, b)
   ; если  делать b$=Chr(b) и затем WriteString(5, b$), то 1 русский символ расшифровывается правильно, но при работе с большим текстом выясняется
   ; что иногда дописывается всякая дополнительная мура и после этого дешифровка ломается.
   ; по такой же причине не срабатывают операции при записи/считывании из памяти.
  CloseFile(5) 
    
    ; дешифровка
 
   OpenFile(5, m$, #PB_UTF8 ) ;без разницы, стоит тут  #PB_UTF8 или ничего не стоит, все рано не работает
      b=ReadByte(5)
      b$=Chr(b ! Asc("5")) ;ДЕшифруем    
      CloseFile(5)
      Debug "получилось="+b$
DeleteFile(m$)

Отредактировано Goga (15.11.2020 14:16:23)

0

2

Не слишком вникая сразу хочу отметить, что кодировки UTF и ASCII различные, это первое что бросилось в глаза.
Второе - вы шифруете и записываете в файл только один байт. Первый. Иначе нужен цикл. Так задумано?
Ну и в третьих. Зачем ксорировать с ключом в один байт, да ещё и не плавающим? Это самое простое, что можно расшифровать. И вообще зачем, если есть встроенные функции по шифрованию, гораздо эффективнее и можно шифровать как строки, так и бинарный файл.

0

3

1. Я знаю, что это различные кодировки, но выводов правильных сделать не могу.
2. конечно, все в цикле. Я спецом все упростил для форума.
3.Ключ там меняется, конечно. Это только для форума.
4. встроенные функции шифрования ?  Сорри, я не знал об этом. я, конечно, поищу инфу.
P.S. да. нашел в справке AESEncoder() , попробую поиграться. Но все же остается вопрос, почему мой пример не работает.
P.S.S. нет, с AESEncoder() у меня тоже проблемы. Он работает с памятью и может оставить считывание кодирования при null-байте. Я уж лучше вручную.

Отредактировано Goga (15.11.2020 13:27:08)

0

4

Я же написал, что разные кодировки. Уберите лишнее при открытии файла либо в настройках компилятора снимите галочку и вопрос отпадёт.
Вы перед тем как отредактировать своё сообщение, спрашивали, зачем шифровать бинарный файл. Так а что такое по вашему файл test.txt?
Именно бинарный файл. Более того, открою вам страшную тайну: все файлы на компьютере бинарные. А уже как представлять информацию из этого файла - это другой вопрос.
При этом, смею вас заверить, что в бинарном файле, нет такого понятия, как null байта.
Загрузите файл test.txt в память как бинарный и используйте AESEncoder()
Это не трудно. И никаких проблем с кодировками не будет.

0

5

Галочку я снять не могу, мне нужен UTF-8. При открытии файла я перепробовал (ну, мне так кажется) все опции- и убирал "лишнее и добавлял". Если вы конкретизируете, что из  "лишнего" надо убрать, было бы здорово.
Про бинарный файл я не это имел ввиду, я хотел бы раскодировать исполняемый файл в памяти, а на диске чтоб он был закодирован. Но подумал, что это как-нибудь, в светлом будущем, поэтому затер упоминание.
Я пробовал кодировать в памяти, потом писать в файл, потом восстанавливать из памяти. Пробовал  без применения AESEncoder(). Были проблемы, я потратил немало времени с этими экспериментами, у меня не работало так, как я хотел. Может, я виноват. Я, конечно, попробую сделать снова уже c AESEncoder() , если так и не смогу получить тут ответ на мой пример выше(ну еще на папа-форум напишу сперва).  Потому как сейчас все отлично, без сбоев работает при латинской кодировке.

Отредактировано Goga (15.11.2020 14:13:23)

0

6

Текст в формате юникода и используется 2 байта на символ, а в файл записывается 1 байт. Неудивительно что часть информации теряется.
Вообще зачем смешивать строки и бинарные данные? Шифруем данные как бинарные. Дешифруем как бинарные и только после этого работаем со строками.

0

7

Только что прочитал в справке про 2 байта! (в описании Unicod-ов) и понял ошибку. Но пока думал, что сделать, вы ответили. Сорри, нет ни знаний/ ни опыта.
можно, чуть подробнее, "Шифруем данные как бинарные. Дешифруем как бинарные, потом работаем со строкой "?

Отредактировано Goga (15.11.2020 16:07:00)

0

8

Я же писал об этом

Timon написал(а):

Загрузите файл test.txt в память как бинарный и используйте AESEncoder()
Это не трудно. И никаких проблем с кодировками не будет.

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

Goga написал(а):

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

Смысла нет от слова никакого. Кто-то должен раскодировать этот экзешник. Будет другой исполняемый файл, не зашифрованный, с алгоритмом и ключами?
Если кто-то захочет влезть в вашу прогу, то это его не остановит.
И закодированный текстовый файл тоже в принципе. Только для простого пользователя компа это сработает, а от взломщика ПО нет.

0

9

Читаете данные из файла функцией ReadData шифруете функцией AESEncoder и записываете в файл функцией WriteData. Данные зашифрованы.
Для расшифровки читаете данные из файла функцией ReadData расшифровываете функцией AESDecoder и записываете в файл функцией WriteData или используете в программе если в файл записывать не нужно.

0

10

Timon написал(а):

Я же писал об этом

Timon написал(а):
Загрузите файл test.txt в память как бинарный и используйте AESEncoder()
Это не трудно. И никаких проблем с кодировками не будет.

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

Goga, если у самого никак не получается, так и напишите - прошу дать готовое решение  8-) Я попозже могу сделать, пока лень, Коневского смотрю на НТВ :D

0

11

Timon, пока готового решеия не прошу ) С AESEncoder-ом, видимо, сам разберусь. Я микропрограмму набросал себе- работает. Но проверить на рельном примере пока не могу, там немного надо попотеть, чтобы внедрить. Видимо, уже до следующих виикэндов. Коневского обязательно досмотрите)
Петр (спасибо ему за участие), тоже вот направил все же к  AESEncoder. Ну, я такой путь и предполагал. Я считывал уже в память файл. только ксорил все вручную оттуда, потом писал, но глючило, работала частично. Вообщем, ладно, я понял, все пути ведут к AESEncoder ))  Отпишу результат тогда через неделю.

А насчет взломщиков ПО. Да, это у меня проблема, бздик. Но он обоснован.  Возможно, надо задуматься о том, чтобы данные расшифровывал удаленный сервер.

0

12

Простейший способ кодирование-раскодирование string.

Код:
Structure char : a.a[0] : EndStructure

Procedure EncDec(*string.char,len,salt)
  For i = 0 To len-1 : *string\a[i] ! ((salt+i) % 256) : Next
EndProcedure
 
string$ = "Это простой тест "+Chr(13)+"Yes, a test!"
salt = 21762                             
strlen = StringByteLength(string$)

EncDec(@string$,strlen,salt)
Debug string$

EncDec(@string$,strlen,salt)
Debug string$

Естественно, можно так же в string считать весь файл и закодировать-раскодировать этим способом.

0

13

Спасибо, Винипур, поизучаю на выходных.

Отредактировано Goga (21.11.2020 09:57:19)

0

14

ВиниПур
Твой вариант самый подходящий для меня(посимвольная кодировка с управляемым  ключом), но я поплыл тут с некоторыми строчками). Мог бы ты или кто дать немного пояснений?

Код:

Structure char ; char- это по 2 байта на символ. Почему в учебнике структуры всегда с именами, у тут просто char? Это же не имя структуры? А где тогда имя?
  a.a[0] ; '.a'- ascII код- 1 байт, а структура 2 байта
EndStructure

Procedure EncodeDecode(*string.char,strlen,salt)
  For i = 0 To strlen-1
    
    *string\a[i]=*string\a[i] ! i ; как работает эта строчка(последовательность процессов)?  Что дает применение структуры?
  Next
EndProcedure
 
string$ = "Это простой тест "+Chr(13)+"Yes, this is a test! €€"
salt = 21762 
strlen = StringByteLength(string$) 

EncodeDecode(@string$,strlen,salt)
Debug string$
EncodeDecode(@string$,strlen,salt)
Debug string$

Отредактировано Goga (21.11.2020 09:58:56)

0

15

Код:
Structure PUTIN
  a.a[0]
EndStructure

Text$ = "Это простой тест "+Chr(13)+"Yes, this is a test! €€"
strlen = StringByteLength(Text$) 
ShowMemoryViewer(@Text$, strlen)
*string.PUTIN = @Text$ ; создаём новую переменную *string, назначаем ей структуру с именем PUTIN и присваиваем ей адрес Text$ (почитай про @)
                     ; теперь строка у нас выглядит как массив данных и с ним легко работать
Debug "первый байт текста: " + *string\a[0]  ; значение из массива с индексом 0
Debug "второй байт текста: " + *string\a[1]  ; значение из массива с индексом 1
Debug "последний байт текста " + *string\a[strlen-1]  ; значение из массива с индексом strlen-1
Debug "======="

For index = 0 To strlen-1
  Debug "Берём значение с индексом " +index+ " ("+*string\a[index]+") и ксорим его на " + index + " и записываем обратно в *string\a["+index+"] = " + Str(*string\a[index] ! index)
  *string\a[index]=*string\a[index] ! index
Next

альтернативный код без использования структур

Код:
Procedure EncodeDecode2(*memory,strlen,salt)
  For offset = 0 To strlen - 1
    byte.b = PeekB(*memory + offset) ; читаем байт из памяти
    Newbyte.b = byte ! offset ; ксорим на offset 
    PokeB (*memory + offset, Newbyte) ; записываем байт обратно в память
  Next
EndProcedure

EncodeDecode(@string$,strlen,salt)
Debug string$
EncodeDecode2(@string$,strlen,salt)
Debug string$

Filename$ = OpenFileRequester("выберите файл", "","",0)
hFile = ReadFile(#PB_Any, Filename$)
lFileSize = FileSize(Filename$)
*Buffer = AllocateMemory(lFileSize)
ReadData(hFile, *Buffer, lFileSize)
EncodeDecode2(*Buffer,lFileSize,0)
NewFilename$ = SaveFileRequester("сохранить файл в ", Filename$ + "_new", "", 0)
hNewFile = CreateFile(#PB_Any, NewFilename$)
WriteData(hNewFile, *Buffer, lFileSize)

Отредактировано Lin (22.11.2020 02:37:54)

0

16

Lin
спасибо, отличные примеры для изучения!

Отредактировано Goga (22.11.2020 09:06:58)

0

17

Предлагаю свой вариант.
1. Шифрует какой-нибудь текст и сохраняет на диск зашифрованный файл.
2. Открывает зашифрованный файл, расшифровывает и получает расшифрованный текст в виде строковой переменной.
Всё без сохранения не шифрованного текста на диск.

Код:
;- Процедуры
Procedure file_cipher (string_to_save$, filename_encrypted_with_path$)
  ;зашифровать текст и сохранить в файл
  txt_len=Len(string_to_save$)*2+1
  *MemoryID_from   = AllocateMemory(txt_len)
  *MemoryID_to = AllocateMemory(txt_len)
  If Not *MemoryID_from Or Not *MemoryID_to
    ProcedureReturn 1; ошибка при выделении памяти
  EndIf
  PokeS (*MemoryID_from, string_to_save$, -1, #PB_Unicode)
  If Not AESEncoder(*MemoryID_from, *MemoryID_to, txt_len, ?Key, 128, 0, #PB_Cipher_ECB)
    ProcedureReturn 3
  EndIf
  If CreateFile(0, filename_encrypted_with_path$)
    WriteData(0, *MemoryID_to, txt_len)
    CloseFile(0) 
    ProcedureReturn 0; выход с нулевым параметром - всё прошло успешно
  EndIf
  ProcedureReturn 2
EndProcedure
Procedure.s file_decipher (filename_encrypted_with_path$)
  ;открыть сохранённый зашифрованный файл, расшифровать и вернуть результат в виде строки
  If ReadFile(0, filename_encrypted_with_path$) 
    file_length = Lof(0)
    *MemoryID_from = AllocateMemory(file_length)
    *MemoryID_to = AllocateMemory(file_length)
    If Not *MemoryID_from Or Not *MemoryID_to
      ProcedureReturn "1"
    EndIf
    bytes_readed = ReadData(0, *MemoryID_from, file_length)
    CloseFile(0)
  Else
    ProcedureReturn "2"
  EndIf
  If Not AESDecoder(*MemoryID_from, *MemoryID_to, file_length, ?Key, 128, 0, #PB_Cipher_ECB)
    ProcedureReturn "3"
  EndIf
    res$=PeekS(*MemoryID_to, -1, #PB_Unicode)
  ProcedureReturn res$; всё прошло успешно, возвращаем расшифрованную строку
EndProcedure
;-Начало программы
filename_encrypted_with_path$="C:\kds\test_1.dat"; зашифрованный файл
string_to_save$="Допустим, есть некоторый текст, который мы хотели бы сохранить в текстовый файл и зашифровать"+#CRLF$+"Используем при этом кодировку UNICODE"
; первое действие - зашифровать текст и сохранить в зашифрованный файл
res_cipher=file_cipher (string_to_save$, filename_encrypted_with_path$)
If res_cipher
  Debug "Can not execute file_cipher() procedure, error code: "+Str(res_cipher)
  End
EndIf
; второе действие - открыть зашифрованный файл, расшифровать и получить текст в переменную
decoded_str$=file_decipher (filename_encrypted_with_path$)
If decoded_str$="1" Or decoded_str$="2" Or decoded_str$="3"
  Debug "Can not execute file_decipher () procedure, error code: "+decoded_str$
  End
EndIf
Debug decoded_str$; расшифрованный текст из зашиврованного файла
End

; ключ для шифрования взят из справки, нужно изменить значения
  DataSection
    Key:
      Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
  EndDataSection

0

18

Есть вообще интересный модуль,  http://forums.purebasic.com/english/vie … mp;t=76163
просто подключаешь и используешь без заморочек с памятью или структурами:

Код:
  AES.AES::AES = AES::New()
  If CreateFile(0, "Test.aes")
    AES\SetKey("I'm the key")
    AES\SetInitVector("I'm the InitVector")

    Text$ = "Это простой тест "+Chr(13)+"Yes, this is a test! €€"
    AES\AES_WriteString(0, Text$)
    AES\AES_WriteByte(0, Varb)
    AES\AES_WriteWord(0, Varw)
    AES\AES_WriteLong(0, Varl) 
    AES\AES_WriteQuad(0, Varq)
    CloseFile(0)
  EndIf

или вот https://www.purebasic.fr/english/viewto … mp;t=73970

Отредактировано Lin (23.11.2020 05:59:23)

0

19

Ребят, все классно! Этот топик мне очень помог. Я обещаю еще грузить вас наивными вопросами, оставайтесь на связи ;) 
Мне, правда, немного другая задача нужна была. Мне нужно было шифровать не текст, а отдельные символы и потом их в определенном порядке складывать, причем НЕ расшифровывая в памяти. считывая с файла.  Чудно я  заморочился ) Еще учитывая, что из меня программер, ну так, нулевой любитель по воскресеньям )  Но этот топик мне дал практикум начального понимания с памятью  и работой с операторами чтения и записи. Вот мой, наконец-то заработавший блок, для моей задачи, на который я уже стал накручивать "мясо".

Код:
m$="d:\Programming\mmm.txt" ; просто левый файл

;-------этот кусок кода запускается один раз, для создания шифрованного файла, потом комментится---
p$="1000ффф"+Chr(13)+"dddёёё" 
len=StringByteLength(p$)
*buffer=@p$ 
Debug "p="+p$

For i=0 To len-1 Step 2
  symbol.c=PeekC(*buffer+i) ; читаем
  symbol=symbol ! i
  PokeC(*buffer+i, symbol)
Next 

Debug "шифр="+p$ ;:End 

OpenFile(5, m$)
WriteData(5, *Buffer, Len)
CloseFile(5)
;--------------------------------------------

; дешифровка
OpenFile(5, m$)
len=Lof(5) ; Определение размера файла в байтах
p$=Space(len)
*buffer=@p$ ;получили адрес памяти
For i=0 To len-1 Step 2
  symbol.c=ReadCharacter(5) ! i
  If symbol=13:Debug "Enter найден!":EndIf  
  PokeC(*buffer+i, symbol) ; пишем
Next 
CloseFile(5)
Debug "считано и дешифровано="+p$
End 

Отредактировано Goga (25.11.2020 15:56:24)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Получить русские символы из файла при раскодировке