OAuth Percent Encoding - replacing characters with hexidecimals

OAuth Core 1.0 5.1 states that when sending headers across the network, you need to encode any characters that are not in the unreserved character set. My current implementation for this is as follows. My string library usage is not as good as it once was, and I’m wondering if there’s a better way to do this.

Essentially: If a character is not in a table, get the ASCII code with string.byte, then covert to hexidecimal with string.format(%X). Then concatenate the string all together. Is there a better easier way to do this?

local OAuthUtil = {
	usedNonces = {},
	unreservedCharacterSet = string.split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~',"")
}
OAuthUtil.__index = OAuthUtil

-- Created by benpinpop. Only functional for OAuth 1.0 --  

-- UTILITY FUNCTIONS --
function OAuthUtil.encodeString(strToEncode: string)
	local stringSplit = string.split(strToEncode, "")
	local lengthOfString = #stringSplit

	for i = 1, lengthOfString do
		if not table.find(OAuthUtil.unreservedCharacterSet, stringSplit[i]) then
			local octetValue = string.format("%X", string.byte(stringSplit[i]))

			stringSplit[i] = `%{octetValue}` 
		end
	end
	
	return table.concat(stringSplit)
end

Your code looks pretty fine to me. I don’t think we can make it truly better in terms of performance, but since the string is being traversed, we could go for string.gsub() with a pattern for reserved characters.

local OAuthUtil = {
    usedNonces = {},
}
OAuthUtil.__index = OAuthUtil

function OAuthUtil.encodeString(strToEncode: string): string
    local encodedStr = string.gsub(strToEncode, "[^%w%-%._~']", function(char)
        return `%{string.format("%X", string.byte(char))}`
    end)
    return encodedStr
end

To verify:
%w for alphanumerics, %- escaped -, %. escaped ., _, and ~; negated with ^

2 Likes