So it's taken some time, but after using the brick-wall method (banging my head against it until it works) I've finally managed to get a working save-safe (mostly) efficient storage metod that can store up to 10 characters. 11 or more characters will cause an overflow, so I've taken the liberty of putting a sanity check in for that.
I wanted to stick to my original rules (1-53, 1 is capital 'A', 27 is lowercase 'a' and 53 is space), meaning I needed 6 bits per character; after doing a little tinkering with binary (specifically trying to come up with a way to handle bitflags for saves) I came up with a method that seems to be working, but has some overhead (2-4 bits) caused by endianness that I'm not sure how to fix.
Anyway, here's the code (Size: 710)
nums={3,34,44,41,40,41,45,48,9,9} local fmt=string.format --Size counting starts on next line function combine(tab) local out=0 if #tab > 10 then trace"Error: Input table too big."end for i=1,#tab do if tab[i] then if tab[i]>53 then tab[i]=53 end out=out+tab[i] out=out<<6 end end return out end function bytify(num) local out={} local i=1 while num>0 do out[i]=num & 0xFF num=(num >> 8) // 1 i=i+1 end return out end function rebuild(tab) local out=0 for i=#tab,1,-1 do if tab[i] then out = (out << 8) out = out + (tab[i]&0xFF) end end return out end function retable(num) local out={} local i=0 while num>0 do if num>0 then out[i]=num&0x3F num=(num>>6)//1 end i=i+1 end local n={} for i=1,#out do n[#out-(i-1)]=out[i] end return n end --Size counting stops at end of previous line --Debug Stuff but shows how to use the code trace("Starting name:\n "..table.concat(nums,',')) val1 = combine(nums) trace("Integer out:\n "..fmt("%0X",val1)) val2 = bytify(val1) trace("Bytes out:\n "..table.concat(val2,",")) val3 = rebuild(val2) trace("Integer confirm:\n "..fmt("%0X",val3)) val4 = retable(val3) trace("Confirm:\n "..table.concat(val4,','))
And a little proof that it's working (as best as I can make it work with my current skills):
This works in tandem with some of my above code (specifically this:
ltrs="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " function str2num(str) local s={} for i=1,#str do s[i]=ltrs:find(str:sub(i,i)) end return s end
to convert the name string into a table. I haven't done the opposite conversion yet, but it wouldn't be that difficult, and you could even forgo the string step altogether if you operated strictly on a table and used a "name()" function or equivalent to convert the table into a string for use in your game.