Discuss Scratch
- Discussion Forums
- » Advanced Topics
- » Encoding usernames into cloud data
- Studio04040807
-
Scratcher
100+ posts
Encoding usernames into cloud data
Scratch usernames have an upper limit of 20 characters, and can only contain characters out of the following:
This gives 38 possible characters that can be in a username and up to 20 characters (the lower limit is 3 characters)
However, if a username was encoded into 20 numbers that each could be one of 38 possible values, there would be no way to detect if a username was under 20 characters. I solved this by using 20 numbers with 39 possible values, with the 39th representing null.
20 numbers with 39 values each can be represented in 32 digits. (39^20=66266211231824447117620880943201, which is 32 digits long.) However, Scratch loses precision when handling numbers this large, so I decided to split the username into 2 sections, each represented by 10 numbers with 39 values. This still has a total of 32 digits, since 39^10=8140406085191601, which is 16 digits long.
32 digits is convenient for cloud variable storage since cloud variables have a limit of 256 digits, meaning exactly 8 usernames could be stored in a cloud variable.
Following are the scripts I made: (Each block uses the “output” variable as an output, and uses “i” for incrementing through the input and “number” in middle steps processing half the username. allowedChars is a list containing the 38 allowed characters, which can be in any order but the order has to stay the same.)
- English letters (case-insensitive, so A and a are treated the same)
- Digits 0-9
- Special characters - and _
This gives 38 possible characters that can be in a username and up to 20 characters (the lower limit is 3 characters)
However, if a username was encoded into 20 numbers that each could be one of 38 possible values, there would be no way to detect if a username was under 20 characters. I solved this by using 20 numbers with 39 possible values, with the 39th representing null.
20 numbers with 39 values each can be represented in 32 digits. (39^20=66266211231824447117620880943201, which is 32 digits long.) However, Scratch loses precision when handling numbers this large, so I decided to split the username into 2 sections, each represented by 10 numbers with 39 values. This still has a total of 32 digits, since 39^10=8140406085191601, which is 16 digits long.
32 digits is convenient for cloud variable storage since cloud variables have a limit of 256 digits, meaning exactly 8 usernames could be stored in a cloud variable.
Following are the scripts I made: (Each block uses the “output” variable as an output, and uses “i” for incrementing through the input and “number” in middle steps processing half the username. allowedChars is a list containing the 38 allowed characters, which can be in any order but the order has to stay the same.)
define username to number (username::custom-arg)Here is a project that should demonstrate these blocks by showing the 8 most recent users to view the project
set [output v] to () //clear output
set [i v] to (0) //preapare i to start incrementing
repeat (2) //processing the two halves of the username
set [number v] to (0) //number is the variable in which we will encode this half of the username
repeat (10) //repeating 10 times for the 10 characters in this half
change [i v] by (1) //increment i (not reset in the loop because it will be used for chars 1-10 and chars 11-20)
set [number v] to ((39)*(number)) //multiply number by 39, essentially shifting over to allow for next character
change [number v] by (item # of (letter (i) of (username::custom-arg)) in [allowedChars v]::list) //add the next character using allowedChars as an encoding table
end
set [output v] to (join (number)(output)) //this will result in the first half being after the last half
end
repeat until <(length of (output))=(32)> //padding output if it is too short
set [output v] to (join (0)(output))
define number to username (number)
set [output v] to () //clear output
set [i v] to (0) //prepare i for incrementing
repeat (2) //two halves of the username
set [number v] to () //clearing number for the next part
repeat (16) //loop that sets (number) to half of the input
change [i v] by (1)
set [number v] to (join (number::variables)(letter (i) of (number::custom-arg)))
end
repeat (10) //10 characters
set [output v] to (join (item ((number::variables) mod (39)) of [allowedChars v])(output))//adds rightmost character to left of output
set [number v] to ([floor v] of ((number::variables)/(39))) //removes rightmost character from number
Last edited by Studio04040807 (March 17, 2020 22:57:00)
- imfh
-
Scratcher
1000+ posts
Encoding usernames into cloud data
Here's the way I encode usernames. It works pretty well and is currently holding 22 usernames along with 2-3 digit scores in the first 2 cloud variables. Link: Leaderboard Demo
The way it works is first by encoding each character into a 2 digit number. The number must always be two digits long, so a 1 would become 01. These encoded numbers are then joined together. abc => 010203.
Next, so the program can tell how long the username is, a number higher than 64 is added to the end. Since there isn't a character represented by a number higher than 64, the program can find the end of the username. abc => 01020364
In addition, a number representing the length of the score is added to the 64. You can also set a minimum length and say 64 means the min length. Score 123 => 64 + 2 = 66
Finally, the score is added to the end of the number. abc score 123 => 010203 67 123 (no spaces in the actual thing). With this format, the usernames and scores can be stored side by side and separated later.
The way it works is first by encoding each character into a 2 digit number. The number must always be two digits long, so a 1 would become 01. These encoded numbers are then joined together. abc => 010203.
Next, so the program can tell how long the username is, a number higher than 64 is added to the end. Since there isn't a character represented by a number higher than 64, the program can find the end of the username. abc => 01020364
In addition, a number representing the length of the score is added to the 64. You can also set a minimum length and say 64 means the min length. Score 123 => 64 + 2 = 66
Finally, the score is added to the end of the number. abc score 123 => 010203 67 123 (no spaces in the actual thing). With this format, the usernames and scores can be stored side by side and separated later.
- Discussion Forums
- » Advanced Topics
-
» Encoding usernames into cloud data