Decimal to Base64 conversion + Custom character list

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Decimal to Base64 conversion + Custom character list

25 Sep 2017, 03:28

Greetings!

I am looking for code that does nothing but give the Base64 equivalent of any decimal integer fed to it, and code to do the reverse. I also would very much like the Base64 character list to be customizable, and do all this in-language, with no dllcalls or similar. Obviously I could do this using hand coded conversion tables and stringreplace, but that would be stupid. :wtf:

I found this code on the archived forum:
https://autohotkey.com/board/topic/5545 ... erdecoder/

Sadly, I can't make head nor tail of the code. I tried tinkering with it to get to the core elements but no joy. And the explanation on that page may as well be in Martian.

Any help will be greatly appreciated. :morebeard:
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

26 Sep 2017, 03:10

It has been 24 hours, and this is about to be pushed to the third page, so... Bump! :wave:
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: Decimal to Base64 conversion + Custom character list

26 Sep 2017, 05:28

So it is just a string to base64 enocder?
If yes -> base64.ahk (via DllCall)
Alternative -> b64Decode (without DllCall - but did just the decode translation so far - and you need to change a bit)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

26 Sep 2017, 06:50

Greetings, jNizM! And thank you for responding.

What I am looking for is a number converter. I only need it to convert from decimal to Base64 and back again. And I need to be able to understand the code in order to use and modify it. The link I posted seems closest to what I need, but I CANNOT understand that code. I appreciate the links you provided, but I am afraid neither will work for me as is, and I certainly have no idea how to change them. :?

Would it be possible to help me understand how I might change any of the afore mentioned code to meet my criteria?

Criteria:
1. Convert decimal integers to Base64 and back again.
2. Customizable character table for the Base64 representation.
3. Done entirely in AutoHotkey language, with no DLLCalls or similar.
4. Final code must be readable, meaning vars have actual names instead of single characters, and a certain degree of code comments and documentation be present. :wtf:

Does this sound possible? Thank you again for responding. 8-)
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

27 Sep 2017, 11:46

... Bump?
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

28 Sep 2017, 18:36

While waiting for replies I continued to work on the code. I have managed to work out enough of the Dec > B64 portion to re write it:

Code: Select all

#noenv
#singleinstance, ignore
setbatchlines, 10ms
setworkingdir, %a_scriptdir%

msgbox % base64(9698625)

Base64(input)
 {
   static chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
   increment := 0
   output := SubStr(chars, (input & 63) + 1, 1)
   loop, 9
    {
      increment+=6
      swap := (input >> increment)
      output := SubStr(chars, (swap & 63) + 1, 1) . output
    }
   return ltrim(output, "A")
 }
I can't say I understand the math involved here but this code appears to work, and can be expanded to handle VERY large numbers.

Now, I have so far failed to adapt the B64 > Dec code to work with my function. Any and all help to do this will be greatly appreciated.

Goal:
Convert the Base64 to Decimal code from my original post so it is compatible with the Decimal to Base64 code in this post. It will need to accept a character string (Base64 integer) and output the equivalent integer in Decimal format.
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Decimal to Base64 conversion + Custom character list

29 Sep 2017, 10:11

Hi dmg,

I don't get what you are trying to achieve. Base64 is designed to encode a sequence of bytes / characters in the range of 0 to 255. If you compare your result with the results of an online encoder or the linked script, you should see that it has nothing to do with Base64.
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

29 Sep 2017, 16:00

Greetings just me! thank you for responding.

I am afraid that isn't quite accurate... Are you maybe thinking of 8 bit binary, where 8 bits/numeric positions represent 256 possible integers (0-255)?

Binary is also known as Base2, because each position can hold two possible digits (0 or 1). Most western cultures use the Decimal system (aka Base10) which uses 10 digits (0-9). Another common one is Base16, aka Hexadecimal, which uses 16 characters (0-9 and A-F) to represent 16 possible values per number column. Base64 works exactly the same way, but uses 64 characters.

Please see these links:
https://simple.wikipedia.org/wiki/Base_(mathematics)
https://www.youtube.com/watch?v=gocwRvLhDf8
http://convertxy.com/index.php/numberbases/

It is true that Base64 is used as part of an encoding system to convert data to a character set with broad compatibility, but that is not what Base64 IS in of itself.

What I want is two functions. One to convert decimal to Base64 and one to convert back again. I have the first, now I need the second. :D
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Decimal to Base64 conversion + Custom character list

29 Sep 2017, 17:16

I need the second

Code: Select all

f(x){
	static chars:="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local k,v,p,y
	p:=strlen(x),y:=0
	for k, v in strsplit(x)
		y+= 64**(p-k)*(instr(chars,v,true)-1)
	return y
}
:morebeard:
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

30 Sep 2017, 07:52

Thank you Helgef! This does indeed appear to do what I wanted. :dance:

Would you be kind, and patient enough to add some information on how the code works? In code comments or just a paragraph on what the elements are doing? Even changing the var names to words relevant to what the vars do would help a lot in my being able to understand it.

Thank you again! :bravo:
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

30 Sep 2017, 07:56

While I am already making a nuisance of myself, could you have a look at the Decimal to Base64 function I posted and see if it can be improved? In particular, at the moment it needs the max number of Base64 number positions to be set in the code, and has to use Trim to remove padding before output. Can these be fixed? :cookie: :cookie: :cookie:
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Decimal to Base64 conversion + Custom character list

30 Sep 2017, 18:48

Hello. The algorithm for your base64 function is fine, the implementation can be tweaked a little, see base10to64
Even changing the var names to words relevant to what the vars do would help a lot
What could be more clear than k,v,p,y,x? :lol:
I have added some comments,

Code: Select all

base64to10(b64){
	; Input:
	; 	b64, a string of n polynomial coefficients, cn-1,...,c0, representing a number in base64,
	; 		 such that the number can be written in base10 as: cn-1*64**(n-1)+cn-2*64**(n-2)...+c0*64**0
	; Output:
	;	b10, the integer represented by b64 in base10.
	;
	; coefficient mapping:	
	;						A ->  0
	;						B ->  1
	;						 ...
	;						/ -> 63
	static coeffMap:="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local k,ck,n,b10
	n:=strlen(b64)												; The number of coefficients in b64 
	b10:=0														; The output
	for k, ck in strsplit(b64)	{								; Visit each coefficient in b64
		ck := instr(coeffMap, ck, true) - 1						; Map the string representation of ck to its base10 equivalent
		b10 += 64**(n-k)*ck										; Increment the sum
	}
	return b10													; Done
}
base10to64(b10) {
	; Input:
	; 	b10, an integer in base10 to be converted to a string of polynomial coefficients
	;		 representing the same number in base64.
	; Output:
	;	b64, a string of n polynomial coefficients, cn-1,...,c0,
	;		 such that b10 = cn-1*64**(n-1)+cn-2*64**(n-2)...+c0*64**0
	static coeffMap := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local b64
	loop {
		b64 := SubStr(coeffMap, (b10 & 63) + 1, 1) . b64	; (b10 & 63) is mod(b10,64)	
		b10 >>= 6											; b10 >>= 6 is  b10 /= 64
	} until !b10
	return b64 
}
Cheers. :wave:
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Decimal to Base64 conversion + Custom character list

01 Oct 2017, 06:03

Hi Helgef,

base10to64:
I had almost the same idea. Don't pass negative integers to the function. ;)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Decimal to Base64 conversion + Custom character list

01 Oct 2017, 06:16

:thumbup: Maybe something like this then,

Code: Select all

msgbox(b64:=base10to64(-100))
msgbox(base64to10(b64))

base64to10(b64){
	; Input:
	; 	b64, a string of n polynomial coefficients, cn-1,...,c0, representing a number in base64,
	; 		 such that the number can be written in base10 as: cn-1*64**(n-1)+cn-2*64**(n-2)...+c0*64**0
	; Output:
	;	b10, the integer represented by b64 in base10.
	;
	; coefficient mapping:	
	;						A ->  0
	;						B ->  1
	;						 ...
	;						/ -> 63
	static coeffMap:="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local k,ck,n,b10,sign:=""
	if (substr(b64,1,1)=="-")
		sign:="-", b64:=ltrim(b64, "-")
	n:=strlen(b64)												; The number of coefficients in b64 
	b10:=0														; The output
	for k, ck in strsplit(b64)	{								; Visit each coefficient in b64
		ck := instr(coeffMap, ck, true) - 1						; Map the string representation of ck to its base10 equivalent
		b10 += 64**(n-k)*ck										; Increment the sum
	}
	return sign . b10											; Done
}
base10to64(b10) {
	; Input:
	; 	b10, an integer in base10 to be converted to a string of polynomial coefficients
	;		 representing the same number in base64.
	; Output:
	;	b64, a string of n polynomial coefficients, cn-1,...,c0,
	;		 such that b10 = cn-1*64**(n-1)+cn-2*64**(n-2)...+c0*64**0
	static coeffMap := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	 
	local b64,sign:=""
	if (b10<0)
		sign:="-", b10*=-1
	
	loop {
		b64 := SubStr(coeffMap, (b10 & 63) + 1, 1) . b64	; (b10 & 63) is mod(b10,64)	
		b10 >>= 6											; b10 >>= 6 is  b10 /= 64
	} until !b10
	return sign . b64 
}
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Decimal to Base64 conversion + Custom character list

01 Oct 2017, 07:33

This seems to work with your original version of base64to10:

Code: Select all

base10to64(b10) {
	; Input:
	; 	b10, an integer in base10 to be converted to a string of polynomial coefficients
	;		 representing the same number in base64.
	; Output:
	;	b64, a string of n polynomial coefficients, cn-1,...,c0,
	;		 such that b10 = cn-1*64**(n-1)+cn-2*64**(n-2)...+c0*64**0
	static coeffMap := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local b64 := SubStr(coeffMap, (b10 & 63) + 1, 1)
   	b10 >>= 6											; b10 >>= 6 is  b10 /= 64
   	b10 &= 0x03FFFFFFFFFFFFFF
   	While (b10) {
		b64 := SubStr(coeffMap, (b10 & 63) + 1, 1) . b64	; (b10 & 63) is mod(b10,64)
		b10 >>= 6											; b10 >>= 6 is  b10 /= 64
	}
	return b64
}
Edit: changed 0x0FFFFFFFFFFFFFFF to 0x03FFFFFFFFFFFFFF
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

01 Oct 2017, 09:00

Ummm... Not to seem ungrateful, but if the last few posts were intended as answers to my posts, then I regret to inform you I find them next to incomprehensible. NAME YOUR VARIABLES AND EXPLAIN YOUR CODE, DARN YOU ALL!

Sorry for the outburst. It is very frustrating to ask questions only to get well meaning, but not entirely helpful answers. It's just... When one is trying to learn something, but the available instruction is well over one's head, it makes the learning more difficult than one wishes it would be.

I really do appreciate everyone taking time to respond at all. Sincerely. :? :? :? :? :? :? :? :?

Edit:
Just saying, if I can't understand this y+= 64**(p-k)*(instr(chars,v,true)-1) as code, then why would cn-1*64**(n-1)+cn-2*64**(n-2)...+c0*64**0 as a comment make it any clearer? :wtf:
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Decimal to Base64 conversion + Custom character list

01 Oct 2017, 10:00

@ just me, seems ok :thumbup:
dmg wrote:if I can't understand this y+= 64**(p-k)*(instr(chars,v,true)-1) as code, then why would cn-1*64**(n-1)+cn-2*64**(n-2)...+c0*64**0 as a comment make it any clearer?
Because now the variables meaning are defined (named) in the comments. I'm not sure how to make it clearer other than improving the textual formatting, I can type it up for you in LaTeX. Making longDescriptiveVariableNames in code will not make it clearer imo, I try,

Code: Select all

base64to10(b64){
	; Input:
	; 	b64, a string of totalNumberOfCoefficients polynomial coefficients representing a number in base64
	; Output:
	;	b10, the integer represented by b64 in base10.
	;
	; coefficient mapping:	
	;						A ->  0
	;						B ->  1
	;						 ...
	;						/ -> 63
	static coeffMap:="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	local theCurrentCoefficientInBase64, theCurrentCoefficientMappedToBase10, totalNumberOfCoefficients, b10
	totalNumberOfCoefficients := strlen(b64)							; The number of coefficients in b64 
	b10:=0																; The output
	arrayOfTheBase64Coefficients:=strsplit(b64)
	for theNumberOfTheCurrentCoefficient, theCurrentCoefficientInBase64 in arrayOfTheBase64Coefficients	{					; Visit each coefficient in b64
		theCurrentCoefficientMappedToBase10 := instr(coeffMap, theCurrentCoefficientInBase64, caseSensitive:=true) - 1		; - 1 due to 1-based index of string position.
		b10 += 64**(totalNumberOfCoefficients-theNumberOfTheCurrentCoefficient)*theCurrentCoefficientMappedToBase10			; Increment the sum
	}
	return b10													; Done
}
More specific questions are also welcome.
Cheers.
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Decimal to Base64 conversion + Custom character list

01 Oct 2017, 10:17

Thank you Helgef. Again, I am sorry for the outburst. I will study all the code posted so far and post back in a few days. I really do appreciate it. :)
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Decimal to Base64 conversion + Custom character list

02 Oct 2017, 04:13

dmg wrote:Thank you Helgef. Again, I am sorry for the outburst. I will study all the code posted so far and post back in a few days. I really do appreciate it. :)
No problems dmg :wave:
Here is a more readable version of the comments defining the B10 - B64 relation,
b64.png
b64.png (2.38 KiB) Viewed 5450 times
b10.png
b10.png (6.28 KiB) Viewed 4540 times
Image credits: latex2png.com

I recommend you try to write a bM:=baseNtoM(BN,N,M) function, it will benefit your understanding.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Decimal to Base64 conversion + Custom character list

07 Oct 2017, 14:03

I haven't tried anybody else's scripts here, but I would ask, what magnitude of number can your functions handle?

This question has prompted me to attempt some 'big int' functions that I had been meaning to write for a long time, i.e. functions than can handle numbers of infinite magnitude, by using string manipulation. Currently the functions can only handle positive integers, and can't handle subtraction or division, but all the difficult bits have been done. They have not been thoroughly tested.

I'm not sure what the best big int library is for AHK, but I know that this is good:
Scientific Maths - infinite precision Mathematics Library - Scripts and Functions - AutoHotkey Community
https://autohotkey.com/board/topic/9351 ... s-library/
Scientific Maths - Math Lib for Unlimited precision - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=465

@dmg: Hopefully everything is reasonably easy to follow here.

Functions so far:
JEE_BigIntAdd(oArray*) ;a sum function
JEE_BigIntMult(oArray*) ;a product function
JEE_BigIntPow(vNum, vPower)
JEE_BigIntCompare(vNum1, vNum2)
JEE_BigIntBaseToDec(vNumX, vBase, vList:="")
JEE_BigIntDecToBase(vNum, vBase, vList:="")

Btw re. base64, the encoding for storing file data, starts with ABC ... rather than 0123 ..., which is a little unusual if you're storing actual numbers.

Code: Select all

q:: ;test big int functions
;MsgBox, % JEE_BigIntAdd(1,2,3)
;MsgBox, % JEE_BigIntAdd(11,22,33)
;MsgBox, % JEE_BigIntMult(16,16)
;MsgBox, % JEE_BigIntMult(1,2,3,4)
;MsgBox, % JEE_BigIntMult(3,3,3,3)
;MsgBox, % JEE_BigIntPow(2,10)
;MsgBox, % JEE_BigIntPow(2,20)
;MsgBox, % JEE_BigIntPow(2,30)
;MsgBox, % JEE_BigIntPow(256,4)
;MsgBox, % JEE_BigIntPow(256,5)
;MsgBox, % JEE_BigIntPow(256,6)
;MsgBox, % JEE_BigIntPow(256,7)
;MsgBox, % JEE_BigIntPow(256,8)
;MsgBox, % JEE_BigIntCompare(11, 22)
;MsgBox, % JEE_BigIntCompare(110, 22)
;MsgBox, % JEE_BigIntCompare(110, 220)
;MsgBox, % JEE_BigIntCompare(11, "011")
;MsgBox, % JEE_BigIntCompare(11, "022")
;MsgBox, % JEE_BigIntBaseToDec("FF", 16)
;MsgBox, % JEE_BigIntBaseToDec("FFF", 16)
;MsgBox, % JEE_BigIntBaseToDec("FFFF", 16)
;MsgBox, % JEE_BigIntBaseToDec(10, 64)
;MsgBox, % JEE_BigIntBaseToDec(100, 64)
;MsgBox, % JEE_BigIntBaseToDec(1000, 64)
MsgBox, % JEE_BigIntDecToBase(0xFF+0, 16)
MsgBox, % JEE_BigIntDecToBase(0xABCDEF+0, 16)
MsgBox, % JEE_BigIntDecToBase(0xFEDCBA+0, 16)
MsgBox, % JEE_BigIntDecToBase(21, 2) ;10101
MsgBox, % JEE_BigIntDecToBase(64, 2) ;1000000
MsgBox, % JEE_BigIntDecToBase(65, 2) ;1000001
return

;==================================================

JEE_BigIntAdd(oArray*)
{
	if !oArray.Length()
		return 0
	vSum := 0
	vWidth := A_IsUnicode ? 2 : 1
	Loop, % oArray.Length()
	{
		vLen1 := StrLen(vSum)
		vLen2 := StrLen(oArray[A_Index])
		vMax := vLen1 > vLen2 ? vLen1 : vLen2
		vNum1 := Format("{:0" vMax "}", vSum)
		vNum2 := Format("{:0" vMax "}", oArray[A_Index])
		vCarry := 0
		vSum := Format("{:0" (vMax+1) "}", 0)
		Loop, % vMax
		{
			vChar1 := SubStr(vNum1, vMax+1-A_Index, 1)
			vChar2 := SubStr(vNum2, vMax+1-A_Index, 1)
			StrPut(Mod(vChar1+vChar2+vCarry,10), &vSum+(vMax+1-A_Index)*vWidth, 1)
			vCarry := (vChar1+vChar2+vCarry >= 10)
		}
		if vCarry
			StrPut(1, &vSum, 1)
		vSum := LTrim(vSum, "0")
	}
	return vSum
}

;==================================================

JEE_BigIntMult(oArray*)
{
	if !oArray.Length()
		return
	else if (oArray.Length() = 1)
		return oArray.1
	vSum := oArray.1
	Loop, % oArray.Length() - 1
	{
		vNum := oArray[A_Index+1]
		if (StrLen(vNum) > StrLen(vSum))
			vTemp := vNum, vNum := vSum, vSum := vTemp
		else
			vTemp := vSum
		vSum := 0
		Loop, Parse, vNum
		{
			vChar := A_LoopField
			oArray2 := {}
			Loop, % vChar ;add original vSum to itself multiple times
				oArray2.Push(vTemp)
			vTemp2 := JEE_BigIntAdd(oArray2*) JEE_StrRept("0", StrLen(vNum)-A_Index)
			vSum := JEE_BigIntAdd(vSum, vTemp2)
		}
	}
	return LTrim(vSum, "0")
}

;==================================================

JEE_BigIntPow(vNum, vPower)
{
	if (vPower = 0)
		if (vNum = 0)
			return
		else
			return 1
	if (vPower = 1)
		return vNum
	oArray := {}
	Loop, % vPower
		oArray.Push(vNum)
	return JEE_BigIntMult(oArray*)
}

;==================================================

;if vNum1 is bigger, return 1
;if vNum1 is smaller, return -1
;if vNum1 and vNum2 are equal, return 0
JEE_BigIntCompare(vNum1, vNum2)
{
	if ("" vNum1 = vNum2)
		return 0
	vNum1 := LTrim(vNum1, "0")
	vNum2 := LTrim(vNum2, "0")
	if ("" vNum1 = vNum2)
		return 0
	if (StrLen(vNum1) > StrLen(vNum2))
		return 1
	else if (StrLen(vNum2) > StrLen(vNum1))
		return -1
	Loop, % StrLen(vNum1)
	{
		vChar1 := SubStr(vNum1,A_Index,1)
		vChar2 := SubStr(vNum2,A_Index,1)
		if (vChar1 > vChar2)
			return 1
		else if (vChar2 > vChar1)
			return -1
		;if (SubStr(vNum1,A_Index,1) > SubStr(vNum2,A_Index,1))
		;	return 1
		;else if (SubStr(vNum2,A_Index,1) > SubStr(vNum2,A_Index,1))
		;	return -1
	}
}

;==================================================

;vList := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;base64
JEE_BigIntBaseToDec(vNumX, vBase, vList:="")
{
	static vList2, oArray
	if (vList = "")
		vList := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"
	if !(vList = vList2)
	{
		oArray := {}
		Loop, Parse, vList
			oArray[Ord(A_LoopField)] := A_Index-1
		vList2 := vList2
	}
	vSum := 0
	vLen := StrLen(vNumX)
	Loop, Parse, vNumX
	{
		vTemp := JEE_BigIntPow(vBase, vLen-A_Index)
		vTemp := JEE_BigIntMult(vTemp, oArray[Ord(A_LoopField)])
		vSum := JEE_BigIntAdd(vSum, vTemp)
	}
	return vSum
}

;==================================================

JEE_BigIntDecToBase(vNum, vBase, vList:="")
{
	static vList2, oArray
	if (vBase = 10)
		return vNum
	else if (vBase < 2)
		return
	if (vList = "")
		vList := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"
	if !(vList = vList2)
	{
		oArray := {}
		Loop, Parse, vList
			oArray[A_Index-1] := A_LoopField
		vList2 := vList2
	}
	vNum := LTrim(vNum, "0")
	if (StrLen(vNum) <= StrLen(vBase))
	&& (vNum+0 < vBase)
		return oArray[vNum]
	vLen := StrLen(vNum)
	if (vBase < 10)
		Loop
		{
			vTemp := JEE_BigIntPow(vBase, vLen)
			if (JEE_BigIntCompare(vTemp, vNum) = 1)
				break
			vLen++
		}
	vSum := 0
	Loop, % vLen
	{
		vTemp := JEE_BigIntPow(vBase, vLen-A_Index)
		vKeep := 0
		Loop, % vBase - 1
		{
			vTemp2 := JEE_BigIntMult(vTemp, A_Index)
			vTemp3 := JEE_BigIntAdd(vSum, vTemp2)
			if (JEE_BigIntCompare(vTemp3, vNum) = 1)
				break
			vKeep := A_Index
			vTemp4 := vTemp3
		}
		if vKeep
			vSum := vTemp4
		vNumX .= oArray[vKeep]
	}
	return LTrim(vNumX, "0")
}

;==================================================

JEE_StrRept(vText, vNum)
{
	if (vNum <= 0)
		return
	return StrReplace(Format("{:" vNum "}","")," ",vText)
	;return StrReplace(Format("{:0" vNum "}",0),0,vText)
}
Btw I would welcome any stand-alone functions specifically optimised for dec to/from base 64, that can/can't handle infinite magnitude. Also, dmg is right, the scripts posted so far, could be better explained, I would welcome any clarifications.

Some algorithm details:
Spoiler
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: ArkuS and 109 guests