1

Тема: AHK: Сравнение массива с массивом

У меня есть два массива.
Мне нужно узнать совпадают ли они.


if array1=array2 				; не работает
	MsgBox 1
if array1=%array2% 				; ложное срабатывание
	MsgBox 2
if array1=% array2 				; ложное срабатывание
	MsgBox 3
if array1[]=array2[] 			; ложное срабатывание
	MsgBox 4
if Array.array1=Array.array2 	; ложное срабатывание
	MsgBox 5

Уже не знаю что делать.

2

Re: AHK: Сравнение массива с массивом

a := ["123", "123", "123", "222"]
b := ["123", "123", "123", "222", "222"]

func(arr1, arr2) {
	if (arr1.MaxIndex() = arr2.MaxIndex()) {
		Loop % arr1.MaxIndex() {
			if (arr1[A_Index] = arr2[A_Index]) {
				continue
			} else {
				return, false
			}
		}
		return, true
	} else {
		return, false
	}
}

msgbox, % func(a, b)

Просто фантазия .

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

3 (изменено: serzh82saratov, 2017-11-06 01:05:03)

Re: AHK: Сравнение массива с массивом

Можно перевести массив в строку, или лучше в хеш сумму, и их сравнивать.


a := ["123", "123", "123", "222"]
b := ["123", "123", "123", "222"]

MsgBox % ObjToBase64(a) = ObjToBase64(b)

ObjToBase64(obj) {
	If !IsObject(obj)
		Return
	VarSetCapacity(Bin, Size := RawObjectSize(obj, 0) + 8, 0)
    RawObject(obj, NumPut(Size - 8, 0 + (addr := &Bin), "Int64"), 0)
	DllCall("Crypt32.dll\CryptBinaryToString"  
		, Ptr, addr, UInt, Size, UInt, 0x00000001|0x40000000, UInt, 0, UIntP, TChars, "CDECL Int")
	VarSetCapacity(Base64, Req := TChars * (A_IsUnicode ? 2 : 1 ))
	DllCall("Crypt32.dll\CryptBinaryToString"  
		, Ptr, addr, UInt, Size, UInt, 0x00000001|0x40000000, Str, Base64, UIntP, Req, "CDECL Int")
	Return Base64
}

RawObject(obj, addr, buf := 0, objects := 0) {
	; Type.Enum:    Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
	; Negative for keys and positive for values
	if !objects
		objects:={(""):0,(obj):0}
	else objects[obj]:=(++objects[""])
	for k,v in obj
	{ ; 9 = Int64 for size and Char for type
		If IsObject(k){
			If objects.HasKey(k)
				NumPut(-12,addr+0,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
			else NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
		}else if (k+0="")
			NumPut(-10,addr+0,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
		else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr+0,"Char")
			,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
			,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v){
			if objects.HasKey(v)
				NumPut( 12,addr+0,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
			else NumPut( 11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
			}else if (v+0="")
		NumPut( 10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(k):&v,"PTR",sz),addr+=sz+9
		else NumPut(InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr+0,"Char")
			,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
			,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
}

RawObjectSize(obj,buf:=0,objects:=0){
	if !objects
		objects:={(obj):1}
	else if !objects.HasKey(obj)
		objects[obj]:=1
	for k,v in obj
	{
		If IsObject(k)
			sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
		else if (k+0="")
			sz+=StrPut(k)*2+9
		else sz+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v)
			sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
		else if (v+0="")
			sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
		else sz+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
	return sz
}

С хэшем:


a := ["123", "123", "123", "222"]
b := ["123", "123", "123", "222"]

MsgBox % ObjToMD5Hash(a) = ObjToMD5Hash(b)

ObjToMD5Hash(obj) {
	If !IsObject(obj)
		Return
	VarSetCapacity(Bin, Size := RawObjectSize(obj, 0) + 8, 0)
    RawObject(obj, NumPut(Size - 8, 0 + (addr := &Bin), "Int64"), 0)
	Return CalcMD5Hash(addr, Size)
}

RawObject(obj, addr, buf := 0, objects := 0) {
	; Type.Enum:    Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
	; Negative for keys and positive for values
	if !objects
		objects:={(""):0,(obj):0}
	else objects[obj]:=(++objects[""])
	for k,v in obj
	{ ; 9 = Int64 for size and Char for type
		If IsObject(k){
			If objects.HasKey(k)
				NumPut(-12,addr+0,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
			else NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
		}else if (k+0="")
			NumPut(-10,addr+0,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
		else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr+0,"Char")
			,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
			,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v){
			if objects.HasKey(v)
				NumPut( 12,addr+0,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
			else NumPut( 11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
			}else if (v+0="")
		NumPut( 10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(k):&v,"PTR",sz),addr+=sz+9
		else NumPut(InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr+0,"Char")
			,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
			,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
}

RawObjectSize(obj,buf:=0,objects:=0){
	if !objects
		objects:={(obj):1}
	else if !objects.HasKey(obj)
		objects[obj]:=1
	for k,v in obj
	{
		If IsObject(k)
			sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
		else if (k+0="")
			sz+=StrPut(k)*2+9
		else sz+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v)
			sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
		else if (v+0="")
			sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
		else sz+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
	return sz
}

CalcMD5Hash(addr, length) {
	Static PROV_RSA_AES := 24, CRYPT_VERIFYCONTEXT := 0xF0000000, HP_HASHVAL := 0x0002, hash := 0, hashlength := 0, hProv := 1
	if (DllCall("advapi32\CryptAcquireContext", PtrP, hProv, Ptr, 0, Ptr, 0, UInt, PROV_RSA_AES, UInt, CRYPT_VERIFYCONTEXT))
		if (DllCall("advapi32\CryptCreateHash", Ptr, hProv, UInt, 32771, UInt, 0, UInt, 0, "Ptr*", hHash))  ;	CALG_MD5 := 32771
			if (DllCall("advapi32\CryptHashData", Ptr, hHash, Ptr, addr, UInt, length, UInt, 0))
				if (DllCall("advapi32\CryptGetHashParam", Ptr, hHash, UInt, HP_HASHVAL, Ptr, 0, UIntP, hashlength, UInt, 0)) {
					VarSetCapacity(hash, hashlength, 0)
					if (DllCall("advapi32\CryptGetHashParam", Ptr, hHash, UInt, HP_HASHVAL, Ptr, &hash, UIntP, hashlength, UInt, 0))
						Loop % hashlength
							hashstr .= Format("{:02X}", *(&hash + A_Index - 1))
				}
	DllCall("advapi32\CryptDestroyHash", Ptr, hHash), DllCall("advapi32\CryptReleaseContext", Ptr, hProv, UInt, 0)
	Return hashstr
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

4

Re: AHK: Сравнение массива с массивом

serzh82saratov
Можно подробнее?
Что за строка?
Что за хеш сумма?
Чем второе лучше первого? 
Разве не будет проще просто перебрать члены массива в две переменные и сравнить их?
Либо сделать как предложил belyankin12?

Да и вообще, от AHK я ожидал встроенной функции.

5 (изменено: belyankin12, 2017-11-06 19:07:01)

Re: AHK: Сравнение массива с массивом

Ну если бы она была serzh бы её точно привел, он гораздо опытнее меня. Я таких функций не знаю, потому сделал свою. В плане эффективности работы все же вариант serzh'a лучше, работает быстрее в том случае, если количество ключей в массивах одинаковое, если же нет, то мой быстрее выдаст отрицательный результат (но речь идёт о 5-10 мс времени, потому не суть). А вот если массив будет огромным, то мой вариант будет гораздо медленнее, но, мой вариант самый простой в плане исполнения: базовые функции, образовавшие костыль - его проще понять. Выбирайте. Кстати, в строку лучше массив не переводить: у строк есть ограничение по длине, а потому можно рано или поздно упереться в него.

И да:

Разве не будет проще просто перебрать члены массива в две переменные и сравнить их?
Либо сделать как предложил belyankin12?

Я как раз это и предложил.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

6

Re: AHK: Сравнение массива с массивом

belyankin12 пишет:

у строк есть ограничение по длине

Нет, ограничение это если прописывать переменную в файле скрипта, если её "создавать" то нет. А, в случае с хэшем, строки будут просто кроче, и сравнивать их "проще".

shahlik002 пишет:

Разве не будет проще просто перебрать члены массива в две переменные и сравнить их?

Проще, если массивы простые, а если ассоциативные и вложенные, то простой способ надо бы доработать.

shahlik002 пишет:

Можно подробнее?

Любой массив переводится в бинарные данные, они в строку Base64 или более короткую хеш сумму этих данных, и далее сравниваются между собой как две строки.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

7 (изменено: serzh82saratov, 2017-11-14 22:43:15)

Re: AHK: Сравнение массива с массивом

Кстати, не уверен, но вроде как строки можно не сравнивать, а можно сравнивать данные.


a := ["123","222"]
b := ["123","222"]

MsgBox % ObjToData(a) = ObjToData(b)

ObjToData(obj) {
	If !IsObject(obj)
		Return
	VarSetCapacity(Bin, Size := RawObjectSize(obj, 0) + 8, 0)
    RawObject(obj, NumPut(Size - 8, 0 + (&Bin), "Int64"), 0)
	Return Bin
}

RawObject(obj, addr, buf := 0, objects := 0) {
	; Type.Enum:    Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
	; Negative for keys and positive for values
	if !objects
		objects:={(""):0,(obj):0}
	else objects[obj]:=(++objects[""])
	for k,v in obj
	{ ; 9 = Int64 for size and Char for type
		If IsObject(k){
			If objects.HasKey(k)
				NumPut(-12,addr+0,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
			else NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
		}else if (k+0="")
			NumPut(-10,addr+0,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
		else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr+0,"Char")
			,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
			,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v){
			if objects.HasKey(v)
				NumPut( 12,addr+0,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
			else NumPut( 11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
			}else if (v+0="")
		NumPut( 10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(k):&v,"PTR",sz),addr+=sz+9
		else NumPut(InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr+0,"Char")
			,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
			,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
}

RawObjectSize(obj,buf:=0,objects:=0){
	if !objects
		objects:={(obj):1}
	else if !objects.HasKey(obj)
		objects[obj]:=1
	for k,v in obj
	{
		If IsObject(k)
			sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
		else 
			sz+=StrPut(k)*2+9
		If IsObject(v)
			sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
		else 
			sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
	}
	return sz
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

8

Re: AHK: Сравнение массива с массивом

Есть у кого мысли по поводу предыдущего поста, не нашёл в справке про то что бинарные данные можно сравнивать.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

9 (изменено: stealzy, 2017-11-14 23:20:09)

Re: AHK: Сравнение массива с массивом

serzh82saratov, как показали мои недавние опыты, небольшие бинарные данные сравнивать можно, но с некого предела простое сравнение дает ложноположительный результат.

st:=A_TickCount
File1 = D:\файл
File2 = D:\файл2
FileGetSize size1, % File1, K
FileGetSize size2, % File2, K
FileRead F1, *c %File1%
FileRead F2, *c %File2%
dur:=A_TickCount-st
MsgBox % (F1==F2) ", Speed - " Round((size1+size2)/dur/0x100000*1000, 3) " Gb/s"

Я остановился на нативном CRC-32, для данных из памяти скорость порядка 130 Мб/с. Видел тесты, где xxHash на порядок превосходил по скорости, но его еще завести надо, без включения бинарного кода не обойдется.

File := "C:\файл"
FileGetSize size, % File, K
st:=A_TickCount
x:=CRC32_File(File)
dur:=A_TickCount-st
MsgBox % Round(size/dur/0x100000*1000, 3) " Gb/s,`nhash =" x
; 50Mb/s, up to 130 after load in memory. xxHash suppose to be 11 times faster in memory.

CRC32_File(filename) {
	if !(f := FileOpen(filename, "r", "UTF-8"))
		throw Exception("Failed to open file: " filename, -1)
	f.Seek(0)
	while (dataread := f.RawRead(data, 262144))
		crc := DllCall("ntdll.dll\RtlComputeCrc32", "uint", crc, "ptr", &data, "uint", dataread, "uint")
	f.Close()
	return Format("{:#x}", crc)
}

10

Re: AHK: Сравнение массива с массивом

По предыдущему посту попробуй:

a := ["123","222"]
b := ["123","222", 333]

MsgBox % ObjToData(a) = ObjToData(b)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

11

Re: AHK: Сравнение массива с массивом

teadrinker
Ноль выдаёт, как и должно.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

12

Re: AHK: Сравнение массива с массивом

stealzy
В 3 посте вариант с MD5, CRC-32 лучше?

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

13 (изменено: stealzy, 2017-11-14 23:43:16)

Re: AHK: Сравнение массива с массивом

Он быстрее, вы ведь не боитесь, что хакеры будут намеренно подделывать хеш массива, чтобы ваш код ошибся?
MD5, SHA это другой тип хешей, намеренно созданных, чтобы осложнить целенаправленный поиск коллизий. Для контроля целостности быстрее будут не имеющие этого свойства хеши.

14

Re: AHK: Сравнение массива с массивом

serzh82saratov пишет:

teadrinker
Ноль выдаёт, как и должно.

Почему должно? У меня, например, 1 выдаёт. Как вы со stealzy пытаетесь сравнивать бинарные данные как строки?

stealzy пишет:
FileRead F1, *c %File1%
FileRead F2, *c %File2%
dur:=A_TickCount-st
MsgBox % (F1==F2) 

Улыбнуло.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

15 (изменено: serzh82saratov, 2017-11-15 00:01:23)

Re: AHK: Сравнение массива с массивом

Да, работает в 4 раза быстрее.


a := ["123", "123", "123", "222"]
b := ["123", "123", "123", "222"]

MsgBox % ObjToCRC32(a) = ObjToCRC32(b)

ObjToCRC32(obj) {
	If !IsObject(obj)
		Return
	VarSetCapacity(Bin, Size := RawObjectSize(obj, 0) + 8, 0)
	RawObject(obj, NumPut(Size - 8, &Bin, "Int64"), 0)
	Return CalcCRC32Hash(&Bin, Size)
}

RawObject(obj, addr, buf := 0, objects := 0) {
	; Type.Enum:    Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
	; Negative for keys and positive for values
	if !objects
		objects:={(""):0,(obj):0}
	else objects[obj]:=(++objects[""])
	for k,v in obj
	{ ; 9 = Int64 for size and Char for type
		If IsObject(k){
			If objects.HasKey(k)
				NumPut(-12,addr+0,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
			else NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
		}else if (k+0="")
			NumPut(-10,addr+0,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
		else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr+0,"Char")
			,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
			,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v){
			if objects.HasKey(v)
				NumPut( 12,addr+0,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
			else NumPut( 11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
			}else if (v+0="")
		NumPut( 10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(k):&v,"PTR",sz),addr+=sz+9
		else NumPut(InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr+0,"Char")
			,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
			,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
}

RawObjectSize(obj,buf:=0,objects:=0){
	if !objects
		objects:={(obj):1}
	else if !objects.HasKey(obj)
		objects[obj]:=1
	for k,v in obj
	{
		If IsObject(k)
			sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
		else 
			sz+=StrPut(k)*2+9
		If IsObject(v)
			sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
		else 
			sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
	}
	return sz
}

CalcCRC32Hash(addr, length) {
	crc := DllCall("ntdll.dll\RtlComputeCrc32", "uint", crc, "ptr", addr, "uint", length, "uint")
	Return Format("{:#x}", crc)
}
По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

16 (изменено: teadrinker, 2017-11-14 23:48:28)

Re: AHK: Сравнение массива с массивом

stealzy пишет:

Улыбнуло измерение скорости чтения с диска или строгое сравнение?

Ну, чтобы долго не объяснять, попробуйте:

FileRead, var, *с %A_AhkPath%
MsgBox, % var
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

17

Re: AHK: Сравнение массива с массивом

teadrinker пишет:

Почему должно? У меня, например, 1 выдаёт.

Массивы из 10 с кодом из 7 у меня ноль, 0. Странно что у нас по разному.

teadrinker пишет:

Ну, чтобы долго не объяснять, попробуйте:

Так остальные данные видимо просто не отображаются как символы.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

18

Re: AHK: Сравнение массива с массивом

serzh82saratov пишет:

Так остальные данные видимо просто не отображаются как символы.

Дело не в том, что они не отображаются. А в том, что AHK под строкой подразумевает то, что справа ограничивается одним или двумя нулевыми байтами. Т. е. при подобной проверке ты сравниваешь только части данных до первых двух нулевых байтов в случае Unicode-версии.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

19

Re: AHK: Сравнение массива с массивом

Понятно, значит так нельзя сравнивать.
По теме, пока считаем 16 пост решением.

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.26.01 (Unicode 32-bit).

20

Re: AHK: Сравнение массива с массивом

stealzy пишет:

Все же интересно, для ресурсов в памяти должен ведь быть способ побитовой сверки?

Winapi-функции вроде нет.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

21

Re: AHK: Сравнение массива с массивом

Нашел. Тема 12 летней давности от Lazlo:
https://autohotkey.com/board/topic/4388 … d-compare/

22

Re: AHK: Сравнение массива с массивом

serzh82saratov пишет:

Есть у кого мысли по поводу предыдущего поста, не нашёл в справке про то что бинарные данные можно сравнивать.

Мож это?

AutoHotkey(RUS).chm пишет:

Переменные и выражения
...
^ Побитовое исключающиее ИЛИ (^)

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

23

Re: AHK: Сравнение массива с массивом

teadrinker пишет:
stealzy пишет:

Все же интересно, для ресурсов в памяти должен ведь быть способ побитовой сверки?

Winapi-функции вроде нет.

RtlCompareMemory?
https://msdn.microsoft.com/en-us/librar … s.85).aspx

24

Re: AHK: Сравнение массива с массивом

https://autohotkey.com/boards/viewtopic … dac5#p9976

MsgBox % FileCompare("D:\Image_004.png"
	, "D:\11.gif")
;Pass a relative or absolute filename for each file1 and file2
;Returns true if the contents of file1 = file2, or false if there are differences
FileCompare(file1, file2)
{
  FileGetSize, sFile1, %file1%
  FileGetSize, sFile2, %file2%
  if (sFile1 != sFile2)
    return 0  ;Not the same size so impossible to have the same contents
  FileRead, bFile1, *c %file1%
  FileRead, bFile2, *c %file2%
  return sFile1 = DllCall("ntdll\RtlCompareMemory", "ptr", &bFile1, "ptr", &bFile2, "ptr", sFile1)
}

Интересно, что Lazlo использовал в своем коде RtlFillMemory, RtlMoveMemory, а для сравнения задействовал memcmp из библиотеки msvcrt.

25

Re: AHK: Сравнение массива с массивом

Оба варианта вроде работают:

VarSetCapacity(var1, 4, 0)
VarSetCapacity(var2, 4, 0)

VarSetCapacity(var3, 4, 0)
VarSetCapacity(var4, 4, 0)

Loop 4  {
   i := A_Index
   Loop 4
      NumPut( (i = 4 && A_Index = 4) ? 2 : 1, var%i%, A_Index - 1, "UChar")  ; четвёртый буфер отличается
}

MsgBox, % DllCall("NtDll\RtlCompareMemory", Ptr, &var1, Ptr, &var2, Ptr, 4, Ptr)
MsgBox, % DllCall("NtDll\RtlCompareMemory", Ptr, &var3, Ptr, &var4, Ptr, 4, Ptr)

MsgBox, % DllCall("msvcrt\memcmp", Ptr, &var1, Ptr, &var2, Ptr, 4)
MsgBox, % DllCall("msvcrt\memcmp", Ptr, &var3, Ptr, &var4, Ptr, 4)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg