How to convert large hex numbers to base 93?

Recently I happened to encounter the problem of having to convert big hexadecimal numbers(base-16) to base 93 for storing inside a datastore(since datastores don’t compress data by themselves and by changing the number base to a higher one significantly decreases the text length and thus the bytes being used) however a problem raised as I was trying to figure out the solution to the problem. When trying to change a number base most of the time the process is the following:

  1. Convert the number from the start base(base-16) to base 10
  2. Convert the base 10 result to the wanted base(base-93)

The algorithms used for those operations are the following:

--For topic simplicity, let's assume that this module encodes and decodes b93 and that's the alphabet
--A similar process is used for encoding and decoding hex as well
local b93a = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz|~"

--Encodes a base10 number to a base93 string
function Encode(n: number): string 
	local result = ""
	repeat
		result ..= string.sub(b93a, n%93+1, n%93+1)
		n = math.floor(n/93)
	until n == 0 
	return result
end

--Decodes a base93 string to a base10 number
function Decode(text: string): number 
	local num = 0
	for i = 1, #text do
		local char = string.sub(text, i, i)
		local byte = string.find(b93a, char, nil, true)
		num += (byte-1)*93^(i-1)
	end
	return num
end

So what’s the issue? The issue is large numbers, you see when performing operations such as decoding a base16 that is huge to a base10 lua string and math functions won’t function properly due to not having enough bytes to store the number properly and thus perform operations on it. So I’m asking for a way of converting to convert base16 to base93 while bypassing the above issues(with math and string libraries acting weird) either through a weird way to bypass the base10 step or by using some sort of custom library for the operations(that store numbers as a string instead and have custom simple equations in them for handling them).

in your particular case there is no way to get around the mathematical operations with large numbers and the only solution would be to use a large number library.

However, there is an alternative if you change the problem a bit. If instead of base 93 you were to use a base power of 2, for example base 64 or 128, then you can convert your number to binary and group the digits according to the base you want. Here is an example of base 16 to base 8:

image

As you can see, it’s just a matter of grouping the binary digits according to the base given.

Are there any open-source large-number libraries available?

InfiniteMath and also EternityNum.

1 Like