Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert encryption to use buffers #1652

Merged
merged 2 commits into from
Nov 3, 2024

Conversation

ccuser44
Copy link
Contributor

This makes it faster

PoF:
image

PoF script:

local function oldEncrypt(str: string?, key: string?, cache: {[string]: any}?)
	cache = cache or {}

	if not key or not str then
		return str
	elseif cache[key] and cache[key][str] then
		return cache[key][str]
	else
		local byte = string.byte
		local sub = string.sub
		local char = string.char

		local keyCache = cache[key] or {}
		local endStr = {}

		for i = 1, #str do
			local keyPos = (i % #key) + 1
			endStr[i] = char(((byte(sub(str, i, i)) + byte(sub(key, keyPos, keyPos)))%126) + 1)
		end

		endStr = table.concat(endStr)
		cache[key] = keyCache
		keyCache[str] = endStr
		return endStr
	end
end

local function oldDecrypt(str: string?, key: string?, cache: {[string]: any}?)
	cache = cache or {}

	if not key or not str then
		return str
	elseif cache[key] and cache[key][str] then
		return cache[key][str]
	else
		local keyCache = cache[key] or {}
		local byte = string.byte
		local sub = string.sub
		local char = string.char
		local endStr = {}

		for i = 1, #str do
			local keyPos = (i % #key)+1
			endStr[i] = char(((byte(sub(str, i, i)) - byte(sub(key, keyPos, keyPos)))%126) - 1)
		end

		endStr = table.concat(endStr)
		cache[key] = keyCache
		keyCache[str] = endStr
		return endStr
	end
end

local function newEncrypt(str: string?, key: string?, cache: {[string]: (string|{[string]: string})}?)
	cache = cache or {}
	local keyCache = cache[key] or {}

	if not key or not str then
		return str
	elseif keyCache[str] then
		return keyCache[str]
	else
		local writeu8, readu8 = buffer.writeu8, buffer.readu8
		local rawStr, rawKey = buffer.fromstring(str), keyCache[1] or buffer.fromstring(key)
		local keyLen = #key

		for i = 1, #str do
			local keyPos = (i % keyLen) + 1
			writeu8(rawStr, (readu8(rawStr, i) + readu8(rawKey, keyPos)) % 126 + 1)
		end

		cache[key] = keyCache
		keyCache[str], keyCache[1] = buffer.tostring(rawStr), rawKey
		return keyCache[str]
	end
end

local function newDecrypt(str: string?, key: string?, cache: {[string]: any}?)
	cache = cache or {}
	local keyCache = cache[key] or {}

	if not key or not str then
		return str
	elseif keyCache[str] then
		return keyCache[str]
	else
		local writeu8, readu8 = buffer.writeu8, buffer.readu8
		local rawStr, rawKey = buffer.fromstring(str), keyCache[1] or buffer.fromstring(key)
		local keyLen = #key

		for i = 1, #str do
			local keyPos = (i % keyLen) + 1
			writeu8(rawStr, (readu8(rawStr, i) - readu8(rawKey, keyPos)) % 126 - 1)
		end

		cache[key] = keyCache
		keyCache[str], keyCache[1] = buffer.tostring(rawStr), rawKey
		return keyCache[str]
	end
end

local STRING_AMOUNT = 5e4

task.wait(5)
print("Creating character list...")
task.wait()

local strings = table.create(STRING_AMOUNT)
local rawLenght = 0

for i = 1, STRING_AMOUNT do
	local str = buffer.create(math.random(1, 6e3))

	for i2 = 0, buffer.len(str) - 1 do
		buffer.writeu8(str, i2, math.random(0, 255))
	end

	if i % 2 ~= 0 then
		rawLenght += buffer.len(str)
	end
	strings[i] = buffer.tostring(str)
end

print("Encrypting characters...")
task.wait(0.1)
local amount = 0
local encryptedLenght = 0
local start = os.clock()

for i = 1, STRING_AMOUNT, 2 do
	local str, key = strings[i], string[i + 2]
	local newEncVal, oldEncVal = newEncrypt(str, key), oldEncrypt(str, key)
	local newDecVal, oldDecVal = newDecrypt(newEncVal, key), oldDecrypt(newEncVal, key)
	local strLen, newEncLen = string.len(str), string.len(newEncVal)

	assert(type(newEncVal) == "string", "New encryption value isn't a string!")
	assert(type(oldEncVal) == "string", "Old encryption value isn't a string!")
	assert(newEncLen == strLen, "New encryption value has an incorrect length!")
	assert(string.len(oldEncVal) == strLen, "Old encryption value has an incorrect length!")
	assert(newEncVal == oldEncVal, "New encrypt returned incorrect value!")
	assert(type(newDecVal) == "string", "New decryption value isn't a string!")
	assert(type(oldDecVal) == "string", "Old decryption value isn't a string!")
	assert(newDecVal == str, "New decryption value isn't original!")
	assert(oldDecVal == str, "Old decryption value isn't original!")
	assert(newDecVal == oldDecVal, "Decryption values don't match!")

	amount += 1
	encryptedLenght += newEncLen
end

assert(encryptedLenght == rawLenght, `Amount of characters doesn't match! Encrypted lenght: {encryptedLenght} Raw lenght: {rawLenght}`)

print("Encryption funcs successfully tested. Amount tested:", amount, "Amount of strings:", #strings, "Took:", tostring(os.clock() - start), "seconds", "Amount of characters encrypted:", encryptedLenght)

@Expertcoderz Expertcoderz added the ✨ enhancement Enhancing or improving existing functionality label Nov 3, 2024
@Expertcoderz Expertcoderz merged commit 9126f44 into Epix-Incorporated:master Nov 3, 2024
2 checks passed
@ccuser44 ccuser44 deleted the patch-22 branch November 3, 2024 06:42
@omwot
Copy link
Contributor

omwot commented Nov 9, 2024

@ccuser44 i encountered issues when testing in a newly created place
image

writeu8 expects 3 arguments, but the third value argument is never passed in both encrypt and decrypt
image

@ccuser44
Copy link
Contributor Author

ccuser44 commented Nov 9, 2024

@ccuser44 i encountered issues when testing in a newly created place image

writeu8 expects 3 arguments, but the third value argument is never passed in both encrypt and decrypt image

Odd... It worked with the test case and the code is the same. I'll take a look.

@ccuser44
Copy link
Contributor Author

ccuser44 commented Nov 9, 2024

Wow good catch. Indeed there was something wrong with the test script causing it work even though it shoudn't have.

@ccuser44
Copy link
Contributor Author

Oh my fucking god, Apparently there was a small 1 character typo that didn't lead to an error in the test case but made it succeed even if it should have failed.
image

I'll make a new pull to fix this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ enhancement Enhancing or improving existing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants