How to write a unicode symbol in lua - unicode
How can I write a Unicode symbol in lua. For example I have to write symbol with 9658
when I write
string.char( 9658 );
I got an error. So how is it possible to write such a symbol.
Lua does not look inside strings. So, you can just write
mychar = "►"
(added in 2015)
Lua 5.3 introduced support for UTF-8 escape sequences:
The UTF-8 encoding of a Unicode character can be inserted in a literal string with the escape sequence \u{XXX} (note the mandatory enclosing brackets), where XXX is a sequence of one or more hexadecimal digits representing the character code point.
You can also use utf8.char(9658).
Here is an encoder for Lua that takes a Unicode code point and produces a UTF-8 string for the corresponding character:
do
local bytemarkers = { {0x7FF,192}, {0xFFFF,224}, {0x1FFFFF,240} }
function utf8(decimal)
if decimal<128 then return string.char(decimal) end
local charbytes = {}
for bytes,vals in ipairs(bytemarkers) do
if decimal<=vals[1] then
for b=bytes+1,2,-1 do
local mod = decimal%64
decimal = (decimal-mod)/64
charbytes[b] = string.char(128+mod)
end
charbytes[1] = string.char(vals[2]+decimal)
break
end
end
return table.concat(charbytes)
end
end
c=utf8(0x24) print(c.." is "..#c.." bytes.") --> $ is 1 bytes.
c=utf8(0xA2) print(c.." is "..#c.." bytes.") --> ¢ is 2 bytes.
c=utf8(0x20AC) print(c.." is "..#c.." bytes.") --> € is 3 bytes.
c=utf8(0x24B62) print(c.." is "..#c.." bytes.") --> 𤭢 is 4 bytes.
Maybe this can help you:
function FromUTF8(pos)
local mod = math.mod
local function charat(p)
local v = editor.CharAt[p]; if v < 0 then v = v + 256 end; return v
end
local v, c, n = 0, charat(pos), 1
if c < 128 then v = c
elseif c < 192 then
error("Byte values between 0x80 to 0xBF cannot start a multibyte sequence")
elseif c < 224 then v = mod(c, 32); n = 2
elseif c < 240 then v = mod(c, 16); n = 3
elseif c < 248 then v = mod(c, 8); n = 4
elseif c < 252 then v = mod(c, 4); n = 5
elseif c < 254 then v = mod(c, 2); n = 6
else
error("Byte values between 0xFE and OxFF cannot start a multibyte sequence")
end
for i = 2, n do
pos = pos + 1; c = charat(pos)
if c < 128 or c > 191 then
error("Following bytes must have values between 0x80 and 0xBF")
end
v = v * 64 + mod(c, 64)
end
return v, pos, n
end
To get broader support for Unicode string content, one approach is slnunicode which was developed as part of the Selene database library. It will give you a module that supports most of what the standard string library does, but with Unicode characters and UTF-8 encoding.
Related
How to get the UTF-8 code from a single character in VBScript
I would like to get the UTF-8 Code of a character, have attempted to use streams but it doesn't seem to work: Example: פ should give 16#D7A4, according to https://en.wikipedia.org/wiki/Pe_(Semitic_letter)#Character_encodings Const adTypeBinary = 1 Dim adoStr, bytesthroughado Set adoStr = CreateObject("Adodb.Stream") adoStr.Charset = "utf-8" adoStr.Open adoStr.WriteText labelString adoStr.Position = 0 adoStr.Type = adTypeBinary adoStr.Position = 3 bytesthroughado = adoStr.Read Msgbox(LenB(bytesthroughado)) 'gives 2 adoStr.Close Set adoStr = Nothing MsgBox(bytesthroughado) ' gives K Note: AscW gives Unicode - not UTF-8
The bytesthroughado is a value of byte() subtype (see 1st output line) so you need to handle it in an appropriate way: Option Explicit Dim ss, xx, ii, jj, char, labelString labelString = "ařЖפ€" ss = "" For ii=1 To Len( labelString) char = Mid( labelString, ii, 1) xx = BytesThroughAdo( char) If ss = "" Then ss = VarType(xx) & " " & TypeName( xx) & vbNewLine ss = ss & char & vbTab For jj=1 To LenB( xx) ss = ss & Hex( AscB( MidB( xx, jj, 1))) & " " Next ss = ss & vbNewLine Next Wscript.Echo ss Function BytesThroughAdo( labelChar) Const adTypeBinary = 1 'Indicates binary data. Const adTypeText = 2 'Default. Indicates text data. Dim adoStream Set adoStream = CreateObject( "Adodb.Stream") adoStream.Charset = "utf-8" adoStream.Open adoStream.WriteText labelChar adoStream.Position = 0 adoStream.Type = adTypeBinary adoStream.Position = 3 BytesThroughAdo = adoStream.Read adoStream.Close Set adoStream = Nothing End Function Output: cscript D:\bat\SO\61368074q.vbs 8209 Byte() a 61 ř C5 99 Ж D0 96 פ D7 A4 € E2 82 AC I used characters ařЖפ€ to demonstrate the functionality of your UTF-8 encoder (the alts8.ps1 PowerShell script comes from another project): alts8.ps1 "ařЖפ€" Ch Unicode Dec CP IME UTF-8 ? IME 0405/cs-CZ; CP852; ANSI 1250 a U+0061 97 …97… 0x61 a Latin Small Letter A ř U+0159 345 …89… 0xC599 Å� Latin Small Letter R With Caron Ж U+0416 1046 …22… 0xD096 Ð� Cyrillic Capital Letter Zhe פ U+05E4 1508 …228… 0xD7A4 פ Hebrew Letter Pe € U+20AC 8364 …172… 0xE282AC â�¬ Euro Sign
converting number to string in matlab
is there a way to convert numbers to str in matlab for example, 30120 turns into cat where c is 03 a is 01 t is 20 here is my progress on RSA encryption/decryption I am trying to decrypt into plain text. % variables p=vpi('22953686867719691230002707821868552601124472329079') q=vpi('30762542250301270692051460539586166927291732754961') e=vpi('555799999999999'); n=(p.*q) phi=((q-1).*(p-1)) % how to convert plaintext to integer mod 26 abc = 'abcdefghijklmnopqrstuvwxyz'; word = 'acryptographicallystrongrandomnumbergeneratorwhichhasbeenproperlyseededwithadequateentropymustbeusedtogeneratetheprimespandqananalysiscomparingmillionsofpublickeysgatheredfromtheinternetwasrecentlycarriedoutbylenstrahughesaugierboskleinjungandwachteracryptographicallystrongrandomnumbergeneratorwhichhasbeenproperlyseededwithadequateentropymustbeused'; [temp1, temp2, temp3, temp4, temp5, temp6, temp7,temp8,temp9] = split(word) [int1,int2,int3,int4,int5,int6,int7,int8,int9] = intsplit(temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9) [encrypt1, encrypt2, encrypt3, encrypt4, encrypt5, encrypt6, encrypt7, encrypt8, encrypt9] = encrypt_this(int1, int2, int3, int4, int5, int6, int7, int8, int9) [decrypt1, decryt2, decrypt3, decrypt4, decryt5, decrypt6,decrypt7, decryt8, decrypt9] = decrypt_this(encrypt1, encrypt2, encrypt3, encrypt4, encrypt5, encrypt6, encrypt7, encrypt8, encrypt9)
From 30120 to 'cat': num = 30120; l = ceil(numel(num2str(num))/2); % number of characters num2 = sprintf('%06i', num); % num in string form, with leading zero if needed % '030120' str = ''; for i = 1:l str = [str char(96+str2num(num2(2*i-1:2*i)))]; end % 96 is the ASCII offset needed to get a=1, c=3 etc like in your example Results in str = 'cat'. I think that's what you want.
preventing overlong forms when parsing UTF-8
I have been working on another UTF-8 parser as a personal exercise, and while my implementation works quite well, and it rejects most malformed sequences (replacing them with U+FFFD), I can't seem to figure out how to implement rejection of overlong forms. Could anyone tell me how to do so? Pseudocode: let w = 0, // the number of continuation bytes pending c = 0, // the currently being constructed codepoint b, // the current byte from the source stream valid(c) = ( (c < 0x110000) && ((c & 0xFFFFF800) != 0xD800) && ((c < 0xFDD0) || (c > 0xFDEF)) && ((c & 0xFFFE) != 0xFFFE)) for each b: if b < 0x80: if w > 0: // premature ending to multi-byte sequence append U+FFFD to output string w = 0 append U+b to output string else if b < 0xc0: if w == 0: // unwanted continuation byte append U+FFFD to output string else: c |= (b & 0x3f) << (--w * 6) if w == 0: // done if valid(c): append U+c to output string else if b < 0xfe: if w > 0: // premature ending to multi-byte sequence append U+FFFD to output string w = (b < 0xe0) ? 1 : (b < 0xf0) ? 2 : (b < 0xf8) ? 3 : (b < 0xfc) ? 4 : 5; c = (b & ((1 << (6 - w)) - 1)) << (w * 6); // ugly monstrosity else: append U+FFFD to output string if w > 0: // end of stream and we're still waiting for continuation bytes append U+FFFD to output string
If you save the number of bytes you'll need (so you save a second copy of the initial value of w), you can compare the UTF32 value of the codepoint (I think you are calling it c) with the number of bytes that were used to encode it. You know that: U+0000 - U+007F 1 byte U+0080 - U+07FF 2 bytes U+0800 - U+FFFF 3 bytes U+10000 - U+1FFFFF 4 bytes U+200000 - U+3FFFFFF 5 bytes U+4000000 - U+7FFFFFFF 6 bytes (and I hope I have done the right math on the left column! Hex math isn't my strong point :-) ) Just as a sidenote: I think there are some logic errors/formatting errors. if b < 0x80 if w > 0 what happens if w = 0? (so for example if you are decoding A)? And shouldn't you reset c when you find an illegal codepoint?
Once you have the decoded character, you can tell how many bytes it should have had if properly encoded just by looking at the highest bit set. If the highest set bit's position is <= 7, the UTF-8 encoding requires 1 octet. If the highest set bit's position is <= 11, the UTF-8 encoding requires 2 octets. If the highest set bit's position is <= 16, the UTF-8 encoding requires 3 octets. etc. If you save the original w and compare it to these values, you'll be able to tell if the encoding was proper or overlong.
I had initially thought that if at any point in time after decoding a byte, w > 0 && c == 0, you have an overlong form. However, it's more complicated than that as Jan pointed out. The simplest answer is probably to have a table like xanatos has, only rejecting anything longer than 4 bytes: if c < 0x80 && len > 1 || c < 0x800 && len > 2 || c < 0x10000 && len > 3 || len > 4: append U+FFFD to output string
Pure Lua implementation of md5
Is there a pure lua implementation of the md5 hashing algorithm? One that doesn't rely on any c or external libraries? There's javascript implementations that don't rely on c or anything, so it ought to be possible with lua. Thanks!
I combined the mentioned lua MD5 library that required bitlib and added in LuaBit to make it a pure lua implementation. As an additional benefit it's structured in such a way that it will work inside of the redis lua scripting environment. Please note that it is extremely slow compared to other non pure lua based implementations. --[[--------------- LuaBit v0.4 ------------------- a bitwise operation lib for lua. http://luaforge.net/projects/bit/ How to use: ------------------- bit.bnot(n) -- bitwise not (~n) bit.band(m, n) -- bitwise and (m & n) bit.bor(m, n) -- bitwise or (m | n) bit.bxor(m, n) -- bitwise xor (m ^ n) bit.brshift(n, bits) -- right shift (n >> bits) bit.blshift(n, bits) -- left shift (n << bits) bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>) Please note that bit.brshift and bit.blshift only support number within 32 bits. 2 utility functions are provided too: bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence) -- high bits first bit.tonumb(bit_tbl) -- convert a bit table into a number ------------------- Under the MIT license. copyright(c) 2006~2007 hanzhao (abrash_han#hotmail.com) --]]--------------- --do ------------------------ -- bit lib implementions local function check_int(n) -- checking not float if(n - math.floor(n) > 0) then error("trying to use bitwise operation on non-integer!") end end local function tbl_to_number(tbl) local n = #tbl local rslt = 0 local power = 1 for i = 1, n do rslt = rslt + tbl[i]*power power = power*2 end return rslt end local function expand(tbl_m, tbl_n) local big = {} local small = {} if(#tbl_m > #tbl_n) then big = tbl_m small = tbl_n else big = tbl_n small = tbl_m end -- expand small for i = #small + 1, #big do small[i] = 0 end end local to_bits = function () end local function bit_not(n) local tbl = to_bits(n) local size = math.max(#tbl, 32) for i = 1, size do if(tbl[i] == 1) then tbl[i] = 0 else tbl[i] = 1 end end return tbl_to_number(tbl) end to_bits = function (n) check_int(n) if(n < 0) then -- negative return to_bits(bit_not(math.abs(n)) + 1) end -- to bits table local tbl = {} local cnt = 1 while (n > 0) do local last = math.mod(n,2) if(last == 1) then tbl[cnt] = 1 else tbl[cnt] = 0 end n = (n-last)/2 cnt = cnt + 1 end return tbl end local function bit_or(m, n) local tbl_m = to_bits(m) local tbl_n = to_bits(n) expand(tbl_m, tbl_n) local tbl = {} local rslt = math.max(#tbl_m, #tbl_n) for i = 1, rslt do if(tbl_m[i]== 0 and tbl_n[i] == 0) then tbl[i] = 0 else tbl[i] = 1 end end return tbl_to_number(tbl) end local function bit_and(m, n) local tbl_m = to_bits(m) local tbl_n = to_bits(n) expand(tbl_m, tbl_n) local tbl = {} local rslt = math.max(#tbl_m, #tbl_n) for i = 1, rslt do if(tbl_m[i]== 0 or tbl_n[i] == 0) then tbl[i] = 0 else tbl[i] = 1 end end return tbl_to_number(tbl) end local function bit_xor(m, n) local tbl_m = to_bits(m) local tbl_n = to_bits(n) expand(tbl_m, tbl_n) local tbl = {} local rslt = math.max(#tbl_m, #tbl_n) for i = 1, rslt do if(tbl_m[i] ~= tbl_n[i]) then tbl[i] = 1 else tbl[i] = 0 end end --table.foreach(tbl, print) return tbl_to_number(tbl) end local function bit_rshift(n, bits) check_int(n) local high_bit = 0 if(n < 0) then -- negative n = bit_not(math.abs(n)) + 1 high_bit = 2147483648 -- 0x80000000 end for i=1, bits do n = n/2 n = bit_or(math.floor(n), high_bit) end return math.floor(n) end -- logic rightshift assures zero filling shift local function bit_logic_rshift(n, bits) check_int(n) if(n < 0) then -- negative n = bit_not(math.abs(n)) + 1 end for i=1, bits do n = n/2 end return math.floor(n) end local function bit_lshift(n, bits) check_int(n) if(n < 0) then -- negative n = bit_not(math.abs(n)) + 1 end for i=1, bits do n = n*2 end return bit_and(n, 4294967295) -- 0xFFFFFFFF end local function bit_xor2(m, n) local rhs = bit_or(bit_not(m), bit_not(n)) local lhs = bit_or(m, n) local rslt = bit_and(lhs, rhs) return rslt end -- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh) -- 10/02/2001 jcw#equi4.com local md5={ff=tonumber('ffffffff',16),consts={}} string.gsub([[ d76aa478 e8c7b756 242070db c1bdceee f57c0faf 4787c62a a8304613 fd469501 698098d8 8b44f7af ffff5bb1 895cd7be 6b901122 fd987193 a679438e 49b40821 f61e2562 c040b340 265e5a51 e9b6c7aa d62f105d 02441453 d8a1e681 e7d3fbc8 21e1cde6 c33707d6 f4d50d87 455a14ed a9e3e905 fcefa3f8 676f02d9 8d2a4c8a fffa3942 8771f681 6d9d6122 fde5380c a4beea44 4bdecfa9 f6bb4b60 bebfbc70 289b7ec6 eaa127fa d4ef3085 04881d05 d9d4d039 e6db99e5 1fa27cf8 c4ac5665 f4292244 432aff97 ab9423a7 fc93a039 655b59c3 8f0ccc92 ffeff47d 85845dd1 6fa87e4f fe2ce6e0 a3014314 4e0811a1 f7537e82 bd3af235 2ad7d2bb eb86d391 67452301 efcdab89 98badcfe 10325476 ]],"(%w+)", function (s) table.insert(md5.consts, tonumber(s,16)) end) --67452301 efcdab89 98badcfe 10325476 ]],"(%w+)", function (s) tinsert(md5.consts,tonumber(s,16)) end) function md5.transform(A,B,C,D,X) local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end local z=function (f,a,b,c,d,x,s,ac) a=bit_and(a+f(b,c,d)+x+ac,md5.ff) -- be *very* careful that left shift does not cause rounding! return bit_or(bit_lshift(bit_and(a,bit_rshift(md5.ff,s)),s),bit_rshift(a,32-s))+b end local a,b,c,d=A,B,C,D local t=md5.consts a=z(f,a,b,c,d,X[ 0], 7,t[ 1]) d=z(f,d,a,b,c,X[ 1],12,t[ 2]) c=z(f,c,d,a,b,X[ 2],17,t[ 3]) b=z(f,b,c,d,a,X[ 3],22,t[ 4]) a=z(f,a,b,c,d,X[ 4], 7,t[ 5]) d=z(f,d,a,b,c,X[ 5],12,t[ 6]) c=z(f,c,d,a,b,X[ 6],17,t[ 7]) b=z(f,b,c,d,a,X[ 7],22,t[ 8]) a=z(f,a,b,c,d,X[ 8], 7,t[ 9]) d=z(f,d,a,b,c,X[ 9],12,t[10]) c=z(f,c,d,a,b,X[10],17,t[11]) b=z(f,b,c,d,a,X[11],22,t[12]) a=z(f,a,b,c,d,X[12], 7,t[13]) d=z(f,d,a,b,c,X[13],12,t[14]) c=z(f,c,d,a,b,X[14],17,t[15]) b=z(f,b,c,d,a,X[15],22,t[16]) a=z(g,a,b,c,d,X[ 1], 5,t[17]) d=z(g,d,a,b,c,X[ 6], 9,t[18]) c=z(g,c,d,a,b,X[11],14,t[19]) b=z(g,b,c,d,a,X[ 0],20,t[20]) a=z(g,a,b,c,d,X[ 5], 5,t[21]) d=z(g,d,a,b,c,X[10], 9,t[22]) c=z(g,c,d,a,b,X[15],14,t[23]) b=z(g,b,c,d,a,X[ 4],20,t[24]) a=z(g,a,b,c,d,X[ 9], 5,t[25]) d=z(g,d,a,b,c,X[14], 9,t[26]) c=z(g,c,d,a,b,X[ 3],14,t[27]) b=z(g,b,c,d,a,X[ 8],20,t[28]) a=z(g,a,b,c,d,X[13], 5,t[29]) d=z(g,d,a,b,c,X[ 2], 9,t[30]) c=z(g,c,d,a,b,X[ 7],14,t[31]) b=z(g,b,c,d,a,X[12],20,t[32]) a=z(h,a,b,c,d,X[ 5], 4,t[33]) d=z(h,d,a,b,c,X[ 8],11,t[34]) c=z(h,c,d,a,b,X[11],16,t[35]) b=z(h,b,c,d,a,X[14],23,t[36]) a=z(h,a,b,c,d,X[ 1], 4,t[37]) d=z(h,d,a,b,c,X[ 4],11,t[38]) c=z(h,c,d,a,b,X[ 7],16,t[39]) b=z(h,b,c,d,a,X[10],23,t[40]) a=z(h,a,b,c,d,X[13], 4,t[41]) d=z(h,d,a,b,c,X[ 0],11,t[42]) c=z(h,c,d,a,b,X[ 3],16,t[43]) b=z(h,b,c,d,a,X[ 6],23,t[44]) a=z(h,a,b,c,d,X[ 9], 4,t[45]) d=z(h,d,a,b,c,X[12],11,t[46]) c=z(h,c,d,a,b,X[15],16,t[47]) b=z(h,b,c,d,a,X[ 2],23,t[48]) a=z(i,a,b,c,d,X[ 0], 6,t[49]) d=z(i,d,a,b,c,X[ 7],10,t[50]) c=z(i,c,d,a,b,X[14],15,t[51]) b=z(i,b,c,d,a,X[ 5],21,t[52]) a=z(i,a,b,c,d,X[12], 6,t[53]) d=z(i,d,a,b,c,X[ 3],10,t[54]) c=z(i,c,d,a,b,X[10],15,t[55]) b=z(i,b,c,d,a,X[ 1],21,t[56]) a=z(i,a,b,c,d,X[ 8], 6,t[57]) d=z(i,d,a,b,c,X[15],10,t[58]) c=z(i,c,d,a,b,X[ 6],15,t[59]) b=z(i,b,c,d,a,X[13],21,t[60]) a=z(i,a,b,c,d,X[ 4], 6,t[61]) d=z(i,d,a,b,c,X[11],10,t[62]) c=z(i,c,d,a,b,X[ 2],15,t[63]) b=z(i,b,c,d,a,X[ 9],21,t[64]) return A+a,B+b,C+c,D+d end -- convert little-endian 32-bit int to a 4-char string local function leIstr(i) local f=function (s) return string.char(bit_and(bit_rshift(i,s),255)) end return f(0)..f(8)..f(16)..f(24) end -- convert raw string to big-endian int local function beInt(s) local v=0 for i=1,string.len(s) do v=v*256+string.byte(s,i) end return v end -- convert raw string to little-endian int local function leInt(s) local v=0 for i=string.len(s),1,-1 do v=v*256+string.byte(s,i) end return v end -- cut up a string in little-endian ints of given size local function leStrCuts(s,...) local o,r=1,{} for i=1,#arg do table.insert(r,leInt(string.sub(s,o,o+arg[i]-1))) o=o+arg[i] end return r end function md5.Calc(s) local msgLen=string.len(s) local padLen=56- msgLen % 64 if msgLen % 64 > 56 then padLen=padLen+64 end if padLen==0 then padLen=64 end s=s..string.char(128)..string.rep(string.char(0),padLen-1) s=s..leIstr(8*msgLen)..leIstr(0) assert(string.len(s) % 64 ==0) local t=md5.consts local a,b,c,d=t[65],t[66],t[67],t[68] for i=1,string.len(s),64 do local X=leStrCuts(string.sub(s,i,i+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4) assert(#X==16) X[0]=table.remove(X,1) -- zero based! a,b,c,d=md5.transform(a,b,c,d,X) end local swap=function (w) return beInt(leIstr(w)) end return string.format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d)) end return md5.Calc("asdf"); -- 912ec803b2ce49e4a541068d495ab570 It is available in this gist.
http://equi4.com/md5/md5calc.lua but that still requires a lib.
There's an old one here but it requires bitlib.
I've refined #Adam Baldwin's solution and made a library that calculates md5 sums in pure Lua, with no external dependencies and no C: https://github.com/kikito/md5.lua Summary of changes: Implemented two functions on the interface, md5.sum and md5.sumhex, that work exactly like their counterparts in the Kepler library, but are implemented in Lua alone. Added a small test suite with using busted. Removed some unused functions Avoided re-creation of anonymous functions when it was not needed Simplified the creation of the constants, and made them private Spacing and naming changes. For now I don't need md5.crypt and md5.decrypt, so I have not implemented those. But I will accept pull requests :)
Three boolean values saved in one tinyint
probably a simple question but I seem to be suffering from programmer's block. :) I have three boolean values: A, B, and C. I would like to save the state combination as an unsigned tinyint (max 255) into a database and be able to derive the states from the saved integer. Even though there are only a limited number of combinations, I would like to avoid hard-coding each state combination to a specific value (something like if A=true and B=true has the value 1). I tried to assign values to the variables so (A=1, B=2, C=3) and then adding, but I can't differentiate between A and B being true from i.e. only C being true. I am stumped but pretty sure that it is possible. Thanks
Binary maths I think. Choose a location that's a power of 2 (1, 2, 4, 8 etch) then you can use the 'bitwise and' operator & to determine the value. Say A = 1, B = 2 , C= 4 00000111 => A B and C => 7 00000101 => A and C => 5 00000100 => C => 4 then to determine them : if( val & 4 ) // same as if (C) if( val & 2 ) // same as if (B) if( val & 1 ) // same as if (A) if((val & 4) && (val & 2) ) // same as if (C and B) No need for a state table. Edit: to reflect comment If the tinyint has a maximum value of 255 => you have 8 bits to play with and can store 8 boolean values in there
binary math as others have said encoding: myTinyInt = A*1 + B*2 + C*4 (assuming you convert A,B,C to 0 or 1 beforehand) decoding bool A = myTinyInt & 1 != 0 (& is the bitwise and operator in many languages) bool B = myTinyInt & 2 != 0 bool C = myTinyInt & 4 != 0
I'll add that you should find a way to not use magic numbers. You can build masks into constants using the Left Logical/Bit Shift with a constant bit position that is the position of the flag of interest in the bit field. (Wow... that makes almost no sense.) An example in C++ would be: enum Flags { kBitMask_A = (1 << 0), kBitMask_B = (1 << 1), kBitMask_C = (1 << 2), }; uint8_t byte = 0; // byte = 0b00000000 byte |= kBitMask_A; // Set A, byte = 0b00000001 byte |= kBitMask_C; // Set C, byte = 0b00000101 if (byte & kBitMask_A) { // Test A, (0b00000101 & 0b00000001) = T byte &= ~kBitMask_A; // Clear A, byte = 0b00000100 } In any case, I would recommend looking for Bitset support in your favorite programming language. Many languages will abstract the logical operations away behind normal arithmetic or "test/set" operations.
Need to use binary... A = 1, B = 2, C = 4, D = 8, E = 16, F = 32, G = 64, H = 128 This means A + B = 3 but C = 4. You'll never have two conflicting values. I've listed the maximum you can have for a single byte, 8 values or (bits).