<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Не сохраняется переменная с двоичным(и) нулями]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=12045&amp;type=atom" />
	<updated>2016-09-28T06:17:48Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=12045</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Не сохраняется переменная с двоичным(и) нулями]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=108062#p108062" />
			<content type="html"><![CDATA[<p>Нашел! Перед функцией обрезки надо было поставить<br /></p><div class="codebox"><pre><code>	if (StrLen(s) = 1)
	s := &quot;0&quot; s</code></pre></div><p>Иначе она опусташает переменную, и из за этого гонит весь цикл. Вопрос снимается.</p>]]></content>
			<author>
				<name><![CDATA[NektoN95]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=32518</uri>
			</author>
			<updated>2016-09-28T06:17:48Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=108062#p108062</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Не сохраняется переменная с двоичным(и) нулями]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=108060#p108060" />
			<content type="html"><![CDATA[<p>Поторопился я с выводами, ошибка где-то по ходу цикла, начинается она после 1081 &quot;оборота&quot;...</p>]]></content>
			<author>
				<name><![CDATA[NektoN95]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=32518</uri>
			</author>
			<updated>2016-09-28T05:34:58Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=108060#p108060</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[AHK: Не сохраняется переменная с двоичным(и) нулями]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=108059#p108059" />
			<content type="html"><![CDATA[<p>Есть код, шифрующий файл. На вход шифрующему циклу подается столько символов, сколько есть в файле (пробовал добавлять в него двоичные нули -функции BinRead они нисколько не мешают. Переменная, отсчитывающая число интераций цикла так-же говорит, что прошло столько &quot;оборотов&quot;, сколько положено. Однако в выходной переменной сохраняются лишь данные до первого двоичного нуля (видно по содержимому файлов и функции StrLen после выхода из цикла). Опираясь на выдержку из описания FileRead<br /></p><div class="quotebox"><blockquote><p>Если указанный файл содержит двоичные нули (которые никогда не встречаются в нормальных текстовых файлах), только текст, предшествующий первому двоичному нулю, будет &quot;виден&quot; для команд и функций AutoHotkey.</p></blockquote></div><p>подозреваю, что выходная переменная все же содержит весь результат шифрования, но ни пользовательская функция-близнец BinRead&#039;а &quot;BinWrite&quot; не видит всего ее содержимого, ни стандартная &quot;FileAppend&quot;. Помогите, люди. Желательно модифицировать BinWrite, что бы она таки справилась со своей задачей, но на крайняк подойдут и другие методы.<br />Вот код:<br /></p><div class="codebox"><pre><code>#SingleInstance,Force
SetBatchLines,-1
SetWorkingDir,%A_ScriptDir%

CheckListDirectory := A_ScriptDir &quot;\CheckFileListW.ten.decrypted&quot;

BinRead(CheckListDirectory,data)
String := data
While Mod(StrLen(String), 2)
    String := &quot;0&quot; String
msgbox % StrLen(String) ;проверяем длинну строки, идущей на вход циклу
Loop % StrLen(String)/2
	{
	if A_Index != 1
	LastOut := toappend ;сохраняем результат прошлой интерации цикла, если она не первая
	interCount := A_Index
   	Outp := &quot;0x&quot; SubStr(String, A_Index*2-1, 2) ;группируем строку по 2 знака и добавляем префикс 16ричного числа
	const := 0x42 ;задаем константу для шифровки первой группы 
	if A_Index = 1
	toappend := outp + const ;шифруем первую группу
	else
	toappend := outp + LastOut ;шифруем все прочие
	num := toappend
	VarSetCapacity(S,65,0)
	DllCall(&quot;msvcrt\_i64toa&quot;, Int64,toappend, Str,s, Int,16) ;конвертируем результат в 16ричное число
	RegExMatch(s, &quot;.{2,2}$&quot;, toappend) ;оставляем только последние 2 цифры и добавляем префикс
	noprefix := toappend ;дублируем переменную для последующей записи в файл без префикса
	toappend := &quot;0x&quot; toappend ;добавляем префикс для дальнейшей корректной работы внутри цикла
	cryptdata := cryptdata noprefix ;добавляем зашифрованный фрагмент к будущему файлу
	}
msgbox, % interCount ;по этой переменной можно узнать количество интераций цикла (должно быть в 2раза меньше длинны строки, пошедшей на вход циклу)
msgbox, % StrLen(cryptdata) ;проверяем длинну строки, вышедшей из цикла.
Savedir := A_ScriptDir &quot;\CheckFileListW.ten.HEXcrypted&quot;
Savedir2 := A_ScriptDir &quot;\CheckFileListW.ten.TXTcrypted&quot;
Savedir3 := A_ScriptDir &quot;\CheckFileListW.ten.AfterRead&quot;
fileappend, %cryptdata%, %Savedir2%
BinWrite(Savedir, cryptdata)
BinWrite(Savedir3, data)


return

;-------------Используемые функции--------------

BinWrite(file, data, n=0, offset=0)
{
   ; Open file for WRITE (0x40..), OPEN_ALWAYS (4): creates only if it does not exists
   h := DllCall(&quot;CreateFile&quot;,&quot;str&quot;,file,&quot;Uint&quot;,0x40000000,&quot;Uint&quot;,0,&quot;UInt&quot;,0,&quot;UInt&quot;,4,&quot;Uint&quot;,0,&quot;UInt&quot;,0)
   IfEqual h,-1, SetEnv, ErrorLevel, -1
   IfNotEqual ErrorLevel,0,Return,0 ; couldn&#039;t create the file

   m = 0                            ; seek to offset
   IfLess offset,0, SetEnv,m,2
   r := DllCall(&quot;SetFilePointerEx&quot;,&quot;Uint&quot;,h,&quot;Int64&quot;,offset,&quot;UInt *&quot;,p,&quot;Int&quot;,m)
   IfEqual r,0, SetEnv, ErrorLevel, -3
   IfNotEqual ErrorLevel,0, {
      t = %ErrorLevel%              ; save ErrorLevel to be returned
      DllCall(&quot;CloseHandle&quot;, &quot;Uint&quot;, h)
      ErrorLevel = %t%              ; return seek error
      Return 0
   }

   TotalWritten = 0
   m := Ceil(StrLen(data)/2)
   If (n &lt;= 0 or n &gt; m)
       n := m
   Loop %n%
   {
      StringLeft c, data, 2         ; extract next byte
      StringTrimLeft data, data, 2  ; remove  used byte
      c = 0x%c%                     ; make it number
      result := DllCall(&quot;WriteFile&quot;,&quot;UInt&quot;,h,&quot;UChar *&quot;,c,&quot;UInt&quot;,1,&quot;UInt *&quot;,Written,&quot;UInt&quot;,0)
      TotalWritten += Written       ; count written
      if (!result or Written &lt; 1 or ErrorLevel)
         break
   }

   IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%

   h := DllCall(&quot;CloseHandle&quot;, &quot;Uint&quot;, h)
   IfEqual h,-1, SetEnv, ErrorLevel, -2
   IfNotEqual t,,SetEnv, ErrorLevel, %t%

   Return TotalWritten
}

/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinRead ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|  - Open binary file
|  - Read n bytes (n = 0: all)
|  - From offset (offset &lt; 0: counted from end)
|  - Close file
|  data (replaced) &lt;- file[offset + 0..n-1]
|  Return #bytes actually read
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BinRead(file, ByRef data, n=0, offset=0)
{
   h := DllCall(&quot;CreateFile&quot;,&quot;Str&quot;,file,&quot;Uint&quot;,0x80000000,&quot;Uint&quot;,3,&quot;UInt&quot;,0,&quot;UInt&quot;,3,&quot;Uint&quot;,0,&quot;UInt&quot;,0)
   IfEqual h,-1, SetEnv, ErrorLevel, -1
   IfNotEqual ErrorLevel,0,Return,0 ; couldn&#039;t open the file

   m = 0                            ; seek to offset
   IfLess offset,0, SetEnv,m,2
   r := DllCall(&quot;SetFilePointerEx&quot;,&quot;Uint&quot;,h,&quot;Int64&quot;,offset,&quot;UInt *&quot;,p,&quot;Int&quot;,m)
   IfEqual r,0, SetEnv, ErrorLevel, -3
   IfNotEqual ErrorLevel,0, {
      t = %ErrorLevel%              ; save ErrorLevel to be returned
      DllCall(&quot;CloseHandle&quot;, &quot;Uint&quot;, h)
      ErrorLevel = %t%              ; return seek error
      Return 0
   }

   TotalRead = 0
   data =
   IfEqual n,0, SetEnv n,0xffffffff ; almost infinite

   format = %A_FormatInteger%       ; save original integer format
   SetFormat Integer, Hex           ; for converting bytes to hex

   Loop %n%
   {
      result := DllCall(&quot;ReadFile&quot;,&quot;UInt&quot;,h,&quot;UChar *&quot;,c,&quot;UInt&quot;,1,&quot;UInt *&quot;,Read,&quot;UInt&quot;,0)
      if (!result or Read &lt; 1 or ErrorLevel)
         break
      TotalRead += Read             ; count read
      c += 0                        ; convert to hex
      StringTrimLeft c, c, 2        ; remove 0x
      c = 0%c%                      ; pad left with 0
      StringRight c, c, 2           ; always 2 digits
      data = %data%%c%              ; append 2 hex digits
   }

   IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%

   h := DllCall(&quot;CloseHandle&quot;, &quot;Uint&quot;, h)
   IfEqual h,-1, SetEnv, ErrorLevel, -2
   IfNotEqual t,,SetEnv, ErrorLevel, %t%

   SetFormat Integer, %format%      ; restore original format
   Totalread += 0                   ; convert to original format
   Return TotalRead
}
</code></pre></div><p>Образец файла во вложении</p>]]></content>
			<author>
				<name><![CDATA[NektoN95]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=32518</uri>
			</author>
			<updated>2016-09-28T04:55:03Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=108059#p108059</id>
		</entry>
</feed>
