[SOLVED] Convert string to raw binary data?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

[SOLVED] Convert string to raw binary data?

03 Aug 2015, 02:36

Code: Select all

f := FileOpen("html.txt", "r")
len := f.length
f.RawRead(bin, len)
The above code is for file. How to convert from a string variable? Thanks.
Last edited by tmplinshi on 03 Aug 2015, 09:02, edited 1 time in total.
User avatar
dd900
Posts: 121
Joined: 27 Oct 2013, 16:03

Re: Convert string to raw binary data?

03 Aug 2015, 04:02

Code: Select all

;test here: https://paulschou.com/tools/xlate/

string := "test StrinG`nstuff!@#$%^&*()"
Binary := StrToBin( string )
msgbox % Binary
clipboard := "", clipboard := Binary


StrToBin( string ) {
	Loop Parse, string
	{
		var := 128
		Transform, bin, Asc, %A_LoopField%
		loop 8 {
			oldbin := bin, bin := bin-var, value := 1
			if ( bin < 0 )
				bin := oldbin, value := 0
			var /= 2, allvalues .= value
		}
	}
	return allvalues
}
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: Convert string to raw binary data?

03 Aug 2015, 04:24

Code: Select all

string := "test string"

MsgBox % CryptBinaryToString(string, 0x00000002)    ; CRYPT_STRING_BINARY         (Pure binary copy.)
MsgBox % CryptBinaryToString(string, 0x00000004)    ; CRYPT_STRING_HEX            (Hexadecimal only.)
MsgBox % CryptBinaryToString(string, 0x00000005)    ; CRYPT_STRING_HEXASCII       (Hexadecimal, with ASCII character display.)
MsgBox % CryptBinaryToString(string, 0x0000000a)    ; CRYPT_STRING_HEXADDR        (Hexadecimal, with ASCII character and address display.)
MsgBox % CryptBinaryToString(string, 0x0000000b)    ; CRYPT_STRING_HEXASCIIADDR   (Hexadecimal, with ASCII character and address display.)
MsgBox % CryptBinaryToString(string, 0x0000000c)    ; CRYPT_STRING_HEXRAW         (A raw hexadecimal string.)

CryptBinaryToString(VarIn, Format)
{
    SizeIn := (Strlen(VarIn) + 1) * 2
    if !(DllCall("crypt32.dll\CryptBinaryToString", "Ptr", &VarIn, "UInt", SizeIn, "UInt", Format, "Ptr", 0, "UInt*", SizeOut))
        return "*" A_LastError
    VarSetCapacity(VarOut, SizeOut << 1, 0)
    if !(DllCall("crypt32.dll\CryptBinaryToString", "Ptr", &VarIn, "UInt", SizeIn, "UInt", Format, "Ptr", &VarOut, "UInt*", SizeOut))
        return "*" A_LastError
    return StrGet(&VarOut)
}

ref:
- CryptBinaryToString function
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Convert string to raw binary data?

03 Aug 2015, 05:27

Thanks for help. But both not I'm looking for.. Sorry I wasn't clear enough.

Below is an example code, but I don't want to use a temporary file.

Code: Select all

StrToBin(Str, ByRef Bin) {
    f := FileOpen(".temp_file", "rw")
    f.Write(Str)
    f.Pos := 0
    f.RawRead(Bin, f.length)
    Return f.length, f.Close()
}

MsgBox, % StrToBin("123", bin)

; Just for checking the result correct or not.
    toHex(bin, hex)
    MsgBox, % hex
Return

toHex( ByRef V, ByRef H, dataSz=0 )  { ; http://goo.gl/b2Az0W (by SKAN)
    P := ( &V-1 ), VarSetCapacity( H,(dataSz*2) ), Hex := "123456789ABCDEF0"
    Loop, % dataSz ? dataSz : VarSetCapacity( V )
        H  .=  SubStr(Hex, (*++P >> 4), 1) . SubStr(Hex, (*P & 15), 1)
}
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: Convert string to raw binary data?

03 Aug 2015, 05:47

The function is not really wrong. Its just giving a unicode string: two bytes per character, plus a null terminator

Unicode: (CryptBinaryToString)
123 = 31 00 32 00 33 00
Ansi: (RawRead)
123 = 31 32 33

But if you only want string to hex, you can use this:

Code: Select all

MsgBox % str2hex("123")   ; ==> 313233

str2hex(str)
{
    static v := A_IsUnicode ? "_i64tow" : "_i64toa"
    loop, parse, str
    {
        VarSetCapacity(s, 65, 0)
        DllCall("msvcrt.dll\" v, "Int64", Asc(A_LoopField), "Str", s, "UInt", 16, "CDECL")
        hex .= s
    }
    return hex
}
or with the "new" Build-In function Format

Code: Select all

MsgBox % str2hex("123")   ; ==> 313233

str2hex(str)
{
    loop, parse, str
        hex .= Format("{:x}", Asc(A_LoopField))
    return hex
}
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Coco-guest

Re: Convert string to raw binary data?

03 Aug 2015, 06:55

tmplinshi wrote:Below is an example code, but I don't want to use a temporary file.
You can use StrPut instead of a file.

Code: Select all

StrPutEx("Hello World", bin, "UTF-16")
MsgBox % StrGet(&bin, "UTF-16")

StrPutEx(str, ByRef VarOrAddress, enc)
{
	if (IsVar := IsByRef(VarOrAddress))
		VarSetCapacity(VarOrAddress, StrPut(str, enc) * ((enc="UTF-16"||enc="CP1200") ? 2 : 1))
	if ((addr := IsVar ? &VarOrAddress : VarOrAddress)+0 != "")
		return StrPut(str, addr, enc)
}
just me
Posts: 9456
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Convert string to raw binary data?

03 Aug 2015, 07:57

Not sure what you want to achieve, but the string buffer of a variable already contains the binary format you get using RawRead().

Code: Select all

String := "123"
MsgBox, % StrLen(String) . " - " . VarSetCapacity(String, -1)
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Convert string to raw binary data?

03 Aug 2015, 08:14

Thanks Coco, that's exactly what I needed!

@jNizM
Good to know more str2hex function, although that's not I want in this question.
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Convert string to raw binary data?

03 Aug 2015, 08:36

@just me
I actually wanted to compress string (html source) to gz, then store the compressed data to sqlite database by using your Class_SQLiteDB.

Code: Select all

len := StrPutEx("<html>...", var, "UTF-8")
r := zlib_Compress(CompressedData , var, len)

zlib_Decompress(Inflated, CompressedData, r, len)
MsgBox % StrGet(&Inflated, len, "UTF-8")
Return

StrPutEx(str, ByRef VarOrAddress, enc)
{
    if (IsVar := IsByRef(VarOrAddress))
        VarSetCapacity(VarOrAddress, StrPut(str, enc) * ((enc="UTF-16"||enc="CP1200") ? 2 : 1))
    if ((addr := IsVar ? &VarOrAddress : VarOrAddress)+0 != "")
        return StrPut(str, addr, enc)
}

; ===================================== zlib.ahk =====================================
; by shajul -- http://www.autohotkey.com/board/topic/63343-zlib/
; Download zlib.dll -- https://www.dropbox.com/s/teklwzo5dmxshjl/Zlib.dll?raw=1

zlib_Compress(Byref Compressed, Byref Data, DataLen, level = -1) {
	nSize := DllCall("zlib1\compressBound", "UInt", DataLen, "Cdecl")
	VarSetCapacity(Compressed,nSize)
	ErrorLevel := DllCall("zlib1\compress2", "ptr", &Compressed, "UIntP", nSize, "ptr", &Data, "UInt", DataLen, "Int"
	               , level    ;level 0 (no compression), 1 (best speed) - 9 (best compression)
	               , "Cdecl") ;0 means Z_OK
	return ErrorLevel ? 0 : nSize
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

zlib_Decompress(Byref Decompressed, Byref CompressedData, DataLen, OriginalSize = -1) {
	OriginalSize := (OriginalSize > 0) ? OriginalSize : DataLen*10 ;should be large enough for most cases
	VarSetCapacity(Decompressed,OriginalSize)
	ErrorLevel := DllCall("zlib1\uncompress", "Ptr", &Decompressed, "UIntP", OriginalSize, "Ptr", &CompressedData, "UInt", DataLen)
	return ErrorLevel ? 0 : OriginalSize
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

gz_compress(infilename, outfilename)
{
	VarSetCapacity(sOutFileName, 260)
	DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", outfilename, "int", -1, "str", sOutFileName, "int", 260, "Uint", 0, "Uint", 0)
	infile := FileOpen(infilename, "r"), outfile := DllCall("zlib1\gzopen", "Str" , sOutFileName , "Str", "wb", "Cdecl")
	if (!infile || !outfile) 
		return 0
	nBufferLen := 8192 ; can be increased if gzbuffer function is called beforehand
	VarSetCapacity(inbuffer,nBufferLen)
	while ((num_read := infile.RawRead(inbuffer, nBufferLen)) > 0) 
		DllCall("zlib1\gzwrite", "UPtr", outfile, "UPtr", &inbuffer, "UInt", num_read, "Cdecl")
	infile.Close()
	DllCall("zlib1\gzclose", "UPtr", outfile, "Cdecl")
	return 1
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

gz_decompress(infilename, outfilename)
{
	VarSetCapacity(sInFileName, 260)
	DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", infilename, "int", -1, "str", sInFileName, "int", 260, "Uint", 0, "Uint", 0)
	infile := DllCall("zlib1\gzopen", "Str" , sInFileName , "Str", "rb", "Cdecl"), outfile := FileOpen(outfilename, "w")
	if (!infile || !outfile) 
		return 0
	VarSetCapacity(buffer,8192) ;can be increased after calling gzbuffer beforehand
	num_read = 0
	while ((num_read := DllCall("zlib1\gzread", "UPtr", infile, "UPtr", &buffer, "UInt", 8192, "Cdecl")) > 0)
		outfile.RawWrite(buffer, num_read)
	DllCall("zlib1\gzclose", "UPtr", infile, "Cdecl")
	infile.Close()
	return 1
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

/*
Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events.
#define Z_OK            0
#define Z_STREAM_END    1
#define Z_NEED_DICT     2
#define Z_ERRNO        (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR   (-3)
#define Z_MEM_ERROR    (-4)
#define Z_BUF_ERROR    (-5)
#define Z_VERSION_ERROR (-6)

Compression levels.
#define Z_NO_COMPRESSION         0
#define Z_BEST_SPEED             1
#define Z_BEST_COMPRESSION       9
#define Z_DEFAULT_COMPRESSION  (-1)
*/
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Convert string to raw binary data?

03 Aug 2015, 08:54

Thanks just me, it works! :)

Code: Select all

var := "<html>..."
len := VarSetCapacity(var, -1)
r := zlib_Compress(CompressedData, var, len)

zlib_Decompress(Inflated, CompressedData, r, len)
MsgBox % StrGet(&Inflated, len, "CP1200")
Return
just me
Posts: 9456
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Convert string to raw binary data?

03 Aug 2015, 09:04

As long as you do all of the stuff using AHK Unicode. Otherwise it might be better to convert the string to UTF-8.
drawback
Posts: 34
Joined: 11 Aug 2016, 11:31

Re: [SOLVED] Convert string to raw binary data?

14 Oct 2016, 17:37

@jNizM

Is there a way to get the unicode string back from the hex values (with a function like hex2str(hexValue)) after using str2hex("some unicode characters")?
revolutiow

Re: [SOLVED] Convert string to raw binary data?

28 Dec 2016, 09:17

The best one:


MsgBox % str2hex("123") ; ==> 313233

str2hex(str)
{
loop, parse, str
hex .= Format("{:x}", Asc(A_LoopField))
return hex
}
lexikos
Posts: 9589
Joined: 30 Sep 2013, 04:07
Contact:

Re: [SOLVED] Convert string to raw binary data?

29 Dec 2016, 02:12

revolutionw, that will not produce a sensible result if any character value is less than 16 or greater than 255, as would be the case for several control characters and thousands of Unicode characters.

The hex values may also vary depending on the version of AutoHotkey (ANSI or Unicode) if the string contains non-ASCII characters.
User avatar
WAZAAAAA
Posts: 88
Joined: 13 Jan 2015, 19:48

Re: [SOLVED] Convert string to raw binary data?

19 Dec 2017, 15:03

To anyone that is going to use @jNizM's code, I would recommend to replace those 0x00000002 0x00000004 etc. with 0x40000002 0x40000004 etc., because the default behavior adds \r\n at the end of strings and no sane person would ever want that. Took me an embarassing amount of time to realize the function was adding those hidden newlines to my stuff lol.
CRYPT_STRING_NOCRLF
0x40000000

Do not append any new line characters to the encoded string. The default behavior is to use a carriage return/line feed (CR/LF) pair (0x0D/0x0A) to represent a new line.

Windows Server 2003 and Windows XP: This value is not supported.
YOU'RE NOT ALEXANDER

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], OrangeCat and 309 guests