BinaryCompare() - improvements welcome

Post your working scripts, libraries and tools
Qriist
Posts: 13
Joined: 11 Sep 2016, 04:02

BinaryCompare() - improvements welcome

17 Aug 2018, 01:30

I have a simple function that makes binary comparisons using only native ahk commands. It works reliably, but is about 60% the speed of fc. If anyone has any thoughts about how to further speed up the code, I'm all ears.

ReadUInt64 is used over ReadUChar because of a very large speed increase, presumably from fewer disk reads.

The return codes are the similar to fc.
-1: There was an unidentified error in the comparison process
0: files are identical
1: data mismatch
2a: couldn't find the first file
2b: couldn't find the second file
3: size mismatch; useful when copying across disks.

Code: Select all

BinaryCompare(File1,File2)
{
	
	F1 := FileOpen(File1,"r") 	;Opens the first file
	If A_LastError = 0
	{
		F1.Close()
		return "2a" ; couldn't find the first file
	}
	
	F2 := FileOpen(File2,"r") 	;Opens the second file
	If A_LastError = 0
	{
		F1.Close()
		F2.Close()
		return "2b" ; couldn't find the second file
	}
	
	If ( F1.length() != F2.length() ) 	;Simple check to ensure it's worth the time to compare
	{
		F1.Close()
		F2.Close()
		return "3" ; size mismatch
	}
	
	Loop, % (F1.length() / 8) + 1 	;uses the file size to set the maximum loops
	{		
		If ( F1.ReaduInt64() != F2.ReaduInt64() )
		{
			F1.Close()
			F2.Close()
			return "1" ; data mismatch
			break
		}
	}
	
	;
	If F1.ateof != 0 ; all is well, you are the proud parent of twins!
	{
		F1.Close()
		F2.Close()
		return "0"
	}
	else ; something has gone horribly, horribly wrong and one of your twins is evil.... but which!?
	{
		F1.Close()
		F2.Close()
		return "-1"
	}		

}
		
User avatar
jeeswg
Posts: 5290
Joined: 19 Dec 2016, 01:58
Location: UK

Re: BinaryCompare() - improvements welcome

17 Aug 2018, 02:21

- Great script.
- In this script, used for creating file hashes, jNizM reads in 0x40000 bytes at a time, instead of 8 bytes at a time, by using f.RawRead(data, 262144).
AHK_CNG/bcrypt_sha1_file.ahk at master · jNizM/AHK_CNG · GitHub
https://github.com/jNizM/AHK_CNG/blob/m ... 1_file.ahk
- You can use this code to check if two sets of binary data match.
ret := DllCall("msvcrt\memcmp", Ptr,&data1, Ptr,&data2, UPtr,size, "Cdecl")
- Also, I would use parentheses here (in some situations, without parentheses, AHK uses legacy handling of if statements):
if (A_LastError = 0)
Although maybe this is needed instead, I can't remember.

Code: Select all

if !F1 := FileOpen(File1,"r")
	return "2a" ; couldn't find the first file
- And I think there is one unnecessary break line.
- You can bunch up like this, but it might look neater as you've done it.
F1.Close(), F2.Close()
- Also, F1.Seek(0), F2.Seek(0) should be used, as file reading skips 2 bytes if UTF-16 or 3 bytes if UTF-8, because of BOMs.
- Also, you could add a check, if both files are 0 bytes then they match.

Return to “Scripts and Functions”

Who is online

Users browsing this forum: adegard, CyL0N and 43 guests