Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[How To] Manipulate Binary data with Pointers


  • Please log in to reply
141 replies to this topic
polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
Great article :)

Rotate( pointer, dataSz=0, factor=47 ) { ; Defaults to ROT47

This seems to be quite faster even though it's not fully optimized:
SetBatchLines -1

file = C:\Program Files\AutoHotkey\license.txt
FileRead, text, %file%

RotAsc(text)
MsgBox, , Rot47, %text%

RotAsc(text)
MsgBox, , Normal, %text%

[color=blue]RotAsc(ByRef v, n = 47) {
	p := &v - 1
	Loop, % VarSetCapacity(v) {
		p++
		c := *p
		If c between 33 and 126
			DllCall("RtlFillMemory", "UInt", p, "UInt", 1, "UChar"
				, c + n - 94 * (c > 126 - n))
	}
}[/color]

Mem2Hex( pointer, dataSz )

Here's another version:
SetBatchLines -1

file = %A_WinDir%\System32\himem.sys ; from your example
FileRead, binary, %file%
MsgBox, % toHex(binary)

[color=blue]toHex(ByRef b, s = 0) {
	f = %A_FormatInteger%
	SetFormat, Integer, H
	Loop, % VarSetCapacity(b) * !s + s
		h := h . *(&b + A_Index - 1)
	SetFormat, Integer, %f%
	Return RegExReplace(h, "(?:0x)?(.)(?:0x|$)", "0$1")
}[/color]
Edit: fixed regular expression in toHex() - see below

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
...but RotASc is different: it only works it n < 94. With an initial reduction of n it might be OK, though.

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Dear Titan, :)

RotAsc() is very fast :shock: :D

Re: toHex()

binary := Chr(1) Chr(2) Chr(3)
MsgBox, % toHex(binary)

The above results in "123" instead of "010203"

:?:

Regards, :)
kWo4Lk1.png

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

The above results in "123" instead of "010203"

Oh soz, just replace the regex with RegExReplace(h, "(?:0x)?(.)(?:0x|$)", "0$1")

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Thanks Titan! :D
kWo4Lk1.png

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

...but RotASc is different: it only works it n < 94. With an initial reduction of n it might be OK, though.

Like I said, that was just a draft version with room for further improvements - particularly in the math where bit masking could replace subtraction(?). Rotation 13 and 47 are only ever used anyway so it's unlikely n would be otherwise.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

I prefer to use pointer++, it is one addition less... :-P

- but one line longer, which AHK has to parse and interpret. It is not clear, which is faster.

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

- but one line longer, which AHK has to parse and interpret. It is not clear, which is faster.

Looks like you're right:
setbatchlines -1
process priority, , r
i = 1000000
t1 = %a_tickcount%
;r1 = 0 ; doesn't make a difference
loop %i% {
	r1++
	x1 := r1 + 1
} t2 = %a_tickcount%
loop %i% {
	x2 := A_Index + 1
} t3 = %a_tickcount%
if (x1 == x2)
	msgbox % t2 - t1 . "`n" . t3 - t2

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Regular expressions look overkill for hex conversion. It works with StringReplace, too, as posted earlier, but one line longer:
toHex(ByRef b, s = 0) {

   f := A_FormatInteger

   SetFormat Integer, H

   Loop % VarSetCapacity(b) * !s + s

      h := h . *(&b+A_Index-1)+256

   StringReplace h, h, 0x1,,All

   SetFormat Integer, %f%

   Return h

}


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

h := h . *(&b+A_Index-1)+256


Thanks :!:
kWo4Lk1.png

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

It works with StringReplace, too, as posted earlier, but one line longer

And thus, significantly slower.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

significantly slower.

How much slower?

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012
~50ms for a single call*

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Before time measurements we have to fix the regular expression. I get funny results with
b = abc`n
MsgBox % toHex(b,5)
It should show 6162630a00.

But I see 20..25% slow down. It might be because of the +256 in each iteration of the loop. A complicated fix of the result at the end should be faster, because it is done with compiled code (RegEx).

polyethene
  • Members
  • 5519 posts
  • Last active: May 17 2015 06:39 AM
  • Joined: 26 Oct 2012

Before time measurements we have to fix the regular expression.

You missed my correction, I'll edit the initial post. The test was done with this btw.

autohotkey.com/net Site Manager

 

Contact me by email (polyethene at autohotkey.net) or message tidbit