Initial commit

This commit is contained in:
2014-11-30 12:23:51 +00:00
commit 63c559ec90
56 changed files with 2543 additions and 0 deletions

View File

@@ -0,0 +1,260 @@
--[[---------------
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 to_bits(n)
check_int(n)
if(n < 0) then
-- negative
return to_bits(bit.bnot(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 tbl_to_number(tbl)
local n = table.getn(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(table.getn(tbl_m) > table.getn(tbl_n)) then
big = tbl_m
small = tbl_n
else
big = tbl_n
small = tbl_m
end
-- expand small
for i = table.getn(small) + 1, table.getn(big) do
small[i] = 0
end
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(table.getn(tbl_m), table.getn(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(table.getn(tbl_m), table.getn(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_not(n)
local tbl = to_bits(n)
local size = math.max(table.getn(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
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(table.getn(tbl_m), table.getn(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
--------------------
-- bit lib interface
bit = {
-- bit operations
bnot = bit_not,
band = bit_and,
bor = bit_or,
bxor = bit_xor,
brshift = bit_rshift,
blshift = bit_lshift,
bxor2 = bit_xor2,
blogic_rshift = bit_logic_rshift,
-- utility func
tobits = to_bits,
tonumb = tbl_to_number,
}
end
--[[
for i = 1, 100 do
for j = 1, 100 do
if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then
error("bit.xor failed.")
end
end
end
--]]

View File

@@ -0,0 +1,95 @@
--[[---------------
Hex v0.4
-------------------
Hex conversion lib for lua.
How to use:
hex.to_hex(n) -- convert a number to a hex string
hex.to_dec(hex) -- convert a hex string(prefix with '0x' or '0X') to number
Part of LuaBit(http://luaforge.net/projects/bit/).
Under the MIT license.
copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
--]]---------------
require 'bit'
do
local function to_hex(n)
if(type(n) ~= "number") then
error("non-number type passed in.")
end
-- checking not float
if(n - math.floor(n) > 0) then
error("trying to apply bitwise operation on non-integer!")
end
if(n < 0) then
-- negative
n = bit.tobits(bit.bnot(math.abs(n)) + 1)
n = bit.tonumb(n)
end
hex_tbl = {'A', 'B', 'C', 'D', 'E', 'F'}
hex_str = ""
while(n ~= 0) do
last = math.mod(n, 16)
if(last < 10) then
hex_str = tostring(last) .. hex_str
else
hex_str = hex_tbl[last-10+1] .. hex_str
end
n = math.floor(n/16)
end
if(hex_str == "") then
hex_str = "0"
end
return "0x" .. hex_str
end
local function to_dec(hex)
if(type(hex) ~= "string") then
error("non-string type passed in.")
end
head = string.sub(hex, 1, 2)
if( head ~= "0x" and head ~= "0X") then
error("wrong hex format, should lead by 0x or 0X.")
end
v = tonumber(string.sub(hex, 3), 16)
return v;
end
--------------------
-- hex lib interface
hex = {
to_dec = to_dec,
to_hex = to_hex,
}
end
--[[
-- test
d = 4341688
h = to_hex(d)
print(h)
print(to_dec(h))
for i = 1, 100000 do
h = hex.to_hex(i)
d = hex.to_dec(h)
if(d ~= i) then
error("failed " .. i .. ", " .. h)
end
end
--]]

View File

@@ -0,0 +1,332 @@
--[[---------------
Noki v0.4
-------------------
Noki is a toolkit to convert Nokia PC Suite backuped SMS to a
unicode .txt file, which is more accessible than the original
.nfb or .nfc.
It works well for Nokia PC Suite 6.5.12 and my mobile phone is
Nokia 7360. There might be some compatibility problem if you
use earlier version of the PC Suite.
How to use:
noki.save_sms('nokia.nfb', 'sms.txt')
Under the MIT license.
Noki is a part of LuaBit(http://luaforge.net/projects/bit/).
copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
--]]---------------
require 'hex'
require 'bit'
do
-- globals
local RETURN = '\13\0\10\0'
local SMS_FILE = '\\MPAPI\\MESSAGES'
local SMS_INBOX = 'PIT_MESSAGE_INBOX'
local SMS_OUTBOX = 'PIT_MESSAGE_OUTBOX'
local SMS_ARCHIVEBOX = 'PIT_MESSAGE_ARCHIVE'
-- output decorator
local SMS_INBOX_DEC = '[INBOX] '
local SMS_OUTBOX_DEC = '[OUTBOX] '
local SMS_ARCHIVE_DEC = '[ARCHIVE] '
-- box type
local BoxType = {
NON = 0,
IN = 1,
OUT = 2,
ARCHIVE = 3,
}
-- feed each char with an extra \0
local function asci_to_uni(asci)
--print("-------")
local uni = ""
for i = 1, string.len(asci) do
local str = string.format('%c\0', string.byte(asci, i))
--print(string.len(str))
uni = uni .. str
end
return uni
end
local function asci_padding(asci, pad)
local uni = ""
for i = 1, string.len(asci) do
local str = string.format('%c', string.byte(asci, i))
--print(string.len(str))
uni = uni .. str .. pad
end
return uni
end
-- shrink the \0 in uni code string
local function uni_to_asci(uni)
local asci = ''
--print('uni len ' .. string.len(uni))
for i = 1, string.len(uni), 2 do
asci = asci .. string.sub(uni, i, i)
end
return asci
end
local function reader(str)
local index = 1
return function (n)
--print('reader>>> idx ' .. index .. " n " .. n)
local sub = string.sub(str, index, index + n - 1)
--[[print(hex.to_hex(string.byte(sub, 1)))
print(hex.to_hex(string.byte(sub, 2)))
print(hex.to_hex(string.byte(sub, 3)))
print(hex.to_hex(string.byte(sub, 4)))
--]]
index = index + n
return sub
end
end
local function read_number(read, n)
local str = read(n)
local rslt = 0
for i = 1, n do
local v = string.byte(str, i)
rslt = bit.bor(rslt, bit.blshift(v, (i-1)*8))
end
return rslt
end
local function read_int(read)
return read_number(read, 4)
end
local function read_short(read)
return read_number(read, 2)
end
local function read_nfb_string(read)
local len = read_int(read)
local unistr = read(len*2)
return unistr
end
local function read_nfb_header(read)
local nfb_header = {
ver = read_int(read),
firmware = read_nfb_string(read),
phone = read_nfb_string(read),
entries = read_int(read),
}
return nfb_header
end
local function read_nfb_file(read)
local nfbf = {}
nfbf.path = read_nfb_string(read)
nfbf.nbytes = read_int(read)
nfbf.bytes = read(nfbf.nbytes)
local stamp = read_int(read)
return nfbf
end
local function read_nfb_dir(read)
local nfbd = {
path = read_nfb_string(read)
}
return nfbd
end
local function save_entry(fp, tbl)
for k, v in pairs(tbl) do
fp:write(v)
fp:write(RETURN)
end
end
-- save sms entries
local function save_sms(fp, ctnt)
-- print("save sms ----")
local in_box = asci_padding(SMS_INBOX, "%z")
local out_box = asci_padding(SMS_OUTBOX, "%z")
local archive_box = asci_padding(SMS_ARCHIVEBOX, "%z")
local line_s = asci_padding("1020", "%z")
local head = asci_padding("1033", "%z")
local tail = asci_padding("1040", "%z")
local service_center_tail = asci_padding("1080", "%z")
local phone_nb = "%+%z%d%z%d%z[%d%z]+" -- default is type 145 with '+'
local phone_nb_129 = string.rep("%d%z", 11) -- phone number type 129 without '+'
local time = "[%d%z]+%-%z%d%z%d%z%-%z%d%z%d%zT%z%d%z%d%z:%z%d%z%d%z"
local pattern = "([^\10]+)\13%z\10%z"
local line_end = "\13%z\10%z"
local lineb, linee = string.find(ctnt, line_end)
local start = 1
local line_number = 1
while(lineb and linee) do
local line = string.sub(ctnt, start, lineb - 1)
--line = string.sub(ctnt, gb, ge)
local type = BoxType.NON
--print('capture ' .. string.len(line))
--print(uni_to_asci(box))
if(string.find(line, in_box)) then
fp:write(asci_to_uni(SMS_INBOX_DEC))
type = BoxType.IN
elseif(string.find(line, out_box)) then
fp:write(asci_to_uni(SMS_OUTBOX_DEC))
type = BoxType.OUT
elseif(string.find(line, archive_box)) then
fp:write(asci_to_uni(SMS_ARCHIVE_DEC))
type = BoxType.ARCHIVE
else
--print(uni_to_asci(line))
io.close(fp)
--error('unknown sms type')
return
end
hb, he = string.find(line, head)
tb, te = string.find(line, tail)
local first_number = ""
-- service center address
sb, se = string.find(line, phone_nb, tb)
--print("" .. sb .. ", " .. se)
if(sb and se) then
--print(uni_to_asci(string.sub(line, sb, se)))
-- keep the find number, if the second find for sender address fails
-- then this number is the sender address
first_number = string.sub(line, sb, se)
else
sb, se = string.find(line, phone_nb_129, tb)
if(not (sb and se)) then
--io.close(fp)
--error("error service center address")
--return
first_number = "empty number"
-- nokia's pc suite may leave the serivce center address empty
end
end
-- sender address
se_old = se
sb, se = string.find(line, phone_nb, se)
--print("" .. sb .. ", " .. se)
local sender_address = ""
if(sb and se) then
--print(uni_to_asci(string.sub(line, sb, se)))
sender_address = string.sub(line, sb, se)
else
sb, se = string.find(line, phone_nb_129, se_old)
if(not (sb and se)) then
--[[
print(line_number)
io.close(fp)
error("error sender address")
--]]
sender_address = first_number
end
end
-- write sender
fp:write(sender_address)
fp:write(" \0")
-- date time
-- out box have no date time slot
if(type ~= BoxType.OUT and first_number ~= "empty number") then
tmb, tme = string.find(line, time, se)
--print('' .. tmb .. ", " .. tme)
if(tmb and tme) then
--print(uni_to_asci(string.sub(line, tmb+1, tme)))
else
io.close(fp)
error("error reading date time")
return
end
fp:write(string.sub(line, tmb+1, tme))
end
fp:write(RETURN)
fp:write(string.sub(line, he+3, tb-3))
fp:write(RETURN)
fp:write(RETURN)
--end
start = linee + 1
lineb, linee = string.find(ctnt, line_end, linee)
line_number = line_number + 1
end
end
-- save sms from a .nfc or .nfb file to a unicode .txt file
local function save_nfx_to(from, too)
local fp = io.open(too, 'wb')
if(not fp) then
error("error opening file " .. too .. " to write")
return
end
v = string.format('%c%c', 255, 254)
-- unicode .txt 'FF FE'
fp:write(v)
-- read the .nfc file
local nokia = io.open(from, 'rb')
if(not nokia) then
error("error open file " .. from .. " to read")
end
local ctnt = nokia:read("*a")
io.close(nokia)
local read = reader(ctnt)
local header = read_nfb_header(read)
--print(header.ver)
--print(header.entries)
for i=1, header.entries do
--print(i)
local type = read_int(read)
if(type == 1) then
-- file entry
--print('file')
local fe = read_nfb_file(read)
--save_entry(fp, fe)
if(uni_to_asci(fe.path) == SMS_FILE) then
local smsctnt = fe.bytes
--print('sms len ' .. fe.nbytes)
save_sms(fp, smsctnt)
return
end
elseif(type == 2) then
-- dir entry
--print('dir')
local fd = read_nfb_dir(read)
--save_entry(fp, fd)
else
io.close(fp)
error('unknown entry type : ' .. hex.to_hex(type))
end
end
io.close(fp)
end
-- noki interface --
noki = {
save_sms = save_nfx_to
}
end -- end block
-- sample
-- noki.save_sms('nokia2.nfb', 'sms2.txt')

View File

@@ -0,0 +1,143 @@
LuaBit
------
LuaBit is a bitwise operation lib completely written in Lua. It's
written in the belief that Lua is self-contained.
The supported operations are: not, and, or, xor, right shift, logic
right shift and left shift.
Several utilities are designed to leverage the power of bit operation:
1. hex: a dec <-> hex number converter
2. utf8: convert utf8 string to ucs2
3. noki: convert nokia pc suite backuped SMS file to .txt
Under the MIT license.
Visit http://luaforge.net/projects/bit/ to get latest version.
Status
------
Now LuaBit is in v0.4.
Release date: Mar 18, 2007
Content
-------
3 files are there for LuaBit:
1) bit.lua
is the bitwise operation lib, all operations are implemented here.
2) hex.lua
is a helper lib for ease of using hex numbers with bitwise
operation.
3) noki.lua
a utility(based on bit and hex) to convert Nokia PC Suite backuped
SMS to a unicode .txt file, which is more accessible than the
original .nfb or .nfc file.
4) utf8.lua
convert utf8 string to ucs2 string
How to use
----------
Bit
---
Just require 'bit' in your project and the bit lib will be
available:
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
Hex
---
For ease of using hex numbers, a utility hex lib is also included in
LuaBit. You can require 'hex' to use them:
hex.to_hex(n) -- convert a number to a hex string
hex.to_dec(hex) -- convert a hex string(prefix with '0x' or '0X') to number
With hex, you can write code like:
bit.band(258, hex.to_dec('0xFF'))
to get the lower 8 bits of 258, that's 2.
Noki
----
require 'noki', to save your sms to .txt file:
noki.save_sms('nokia.nfb', 'sms.txt')
and you can view the output sms.txt in notepad or other editor which
support unicode.
Utf8
----
require 'utf8', to convert a utf8 string:
ucs2_string = utf8.utf_to_uni(utf8_string)
History
-------
v0.4
* utf8 to ucs2 converter(utf8.lua).
* clean up for compatible with Lua5.1 and 5.0.
* add 'How to use' section for bit.lua and hex.lua.
v0.3
* noki added as an application of bit.
* typo correction.
v0.2
* add logic right shift(>>>) support: bit.blogic_rshift.
* add 2 utility functions: bit.tobits and bit.tonumb.
* update hex.to_hex(in hex.lua) to support negative number.
v0.1
LuaBit is written when I do my own game project(Fio at http://fio.edithis.info).
When loading resources, I have to do some bit operation. And I do not
like the embedded way of bit operation. So I decide to implement those
ops in lua. And that's LuaBit. It's not as fast as the embedded one, but
it works. And Lua is self-contained :-)
To-Do List
---------
v0.1
It'll be useful if LuaBit support those bitwise op like:
bit.band(258, '0xFF')
ease to type and use. This will be supported in next release.
v0.2
I decide to delay this feature to later version for it'll mess up the
interface of LuaBit.
v0.3
May more utility functions add to Noki - phonebook might be a nice candidate.
v0.4
There's no UCS2 -> UTF8 convertion now, this feature may add in next release
or when the project need.
Noki'll be be exluded from LuaBit in next release; I decide to let Noki grow
into a powerful tool to support more Nokia PC Suite backup format(.nfb,
.nfc and .nbu).
Trial Noki demo at http://nokisms.googlepages.com/(in Chinese)
Known issues
------------
LuaBit doesn't play very well with negative number. The return value of the
bitwise operations might change to positive when applied on negative numbers
though the bit sequence is correct. So if you want do some arithmetic with
the result of bit operation, be careful.
Feedback
--------
Please send your comments, bugs, patches or change request to
hanzhao(abrash_han@hotmail.com).

View File

@@ -0,0 +1,163 @@
--[[---------------
Utf8 v0.4
-------------------
utf8 -> unicode ucs2 converter
How to use:
to convert:
ucs2_string = utf8.utf_to_uni(utf8_string)
to view a string in hex:
utf8.print_hex(str)
Under the MIT license.
Utf8 is a part of LuaBit Project(http://luaforge.net/projects/bit/).
copyright(c) 2007 hanzhao (abrash_han@hotmail.com)
--]]---------------
require 'hex'
require 'bit'
do
local BYTE_1_HEAD = hex.to_dec('0x00') -- 0### ####
local BYTE_2_HEAD = hex.to_dec('0xC0') -- 110# ####
local BYTE_3_HEAD = hex.to_dec('0xE0') -- 1110 ####
-- mask to get the head
local BYTE_1_MASK = hex.to_dec('0x80') -- 1### ####
local BYTE_2_MASK = hex.to_dec('0xE0') -- 111# ####
local BYTE_3_MASK = hex.to_dec('0xF0') -- 1111 ####
-- tail byte mask
local TAIL_MASK = hex.to_dec('0x3F') -- 10## ####
local mask_tbl = {
BYTE_3_MASK,
BYTE_2_MASK,
BYTE_1_MASK,
}
local head_tbl = {
BYTE_3_HEAD,
BYTE_2_HEAD,
BYTE_1_HEAD,
}
local len_tbl = {
[BYTE_1_HEAD] = 1,
[BYTE_2_HEAD] = 2,
[BYTE_3_HEAD] = 3,
}
local function utf_read_char(utf, start)
local head_byte = string.byte(utf, start)
--print('head byte ' .. hex.to_hex(head_byte))
for m = 1, table.getn(mask_tbl) do
local mask = mask_tbl[m]
-- head match
local head = bit.band(head_byte, mask)
--print('head ' .. hex.to_hex(head) .. ' ' .. hex.to_hex(mask))
if(head == head_tbl[m]) then
local len = len_tbl[head_tbl[m]]
--print('len ' .. len)
local tail_idx = start + len - 1
local char = 0
-- tail
for i = tail_idx, start + 1, -1 do
local tail_byte = string.byte(utf, i)
local byte = bit.band(tail_byte, TAIL_MASK)
--print('byte ' .. hex.to_hex(byte).. ' = ' .. hex.to_hex(tail_byte) .. '&'..hex.to_hex(TAIL_MASK))
if(tail_idx - i > 0) then
local sft = bit.blshift(byte, (tail_idx - i) * 6)
--print('shift ' .. hex.to_hex(sft) .. ' ' .. hex.to_hex(byte) .. ' ' .. ((tail_idx - i) * 6))
char = bit.bor(char, sft)
--print('char ' .. hex.to_hex(char))
else
char = byte
end
end -- tails
-- add head
local head_val = bit.band(head_byte, bit.bnot(mask))
--print('head val ' .. hex.to_hex(head_val))
head_val = bit.blshift(head_val, (len-1) * 6)
--print('head val ' .. hex.to_hex(head_val))
char = bit.bor(head_val, char)
--print('char ' .. hex.to_hex(char))
return char, len
end -- if head match
end -- for mask
error('not find proper head mask')
end
local function print_hex(str)
local cat = ''
for i=1, string.len(str) do
cat = cat .. ' ' .. hex.to_hex(string.byte(str, i))
end
print(cat)
end
local HI_MASK = hex.to_dec('0xF0')
local LO_MASK = hex.to_dec('0xFF')
local function char_to_str(char)
local hi, lo = bit.brshift(char, 8), bit.band(char, LO_MASK)
-- print(hex.to_hex(char)..' '..hex.to_hex(hi)..' ' .. hex.to_hex(lo))
if(hi == 0) then
return string.format('%c\0', lo)
elseif(lo == 0) then
return string.format('\0%c', hi)
else
return string.format('%c%c', lo, hi)
end
end
local function utf_to_uni(utf)
local n = string.len(utf)
local i = 1
local uni = ''
while(i <= n) do
--print('---')
char, len = utf_read_char(utf, i)
i = i + len
--print(string.len(char_to_str(char)))
uni = uni..char_to_str(char)
end
--print_hex(uni)
return uni
end
-- interface
utf8 = {
utf_to_uni = utf_to_uni,
print_hex = print_hex,
}
end
--[[
-- test
byte_3 = string.format('%c%c%c', hex.to_dec('0xE7'), hex.to_dec('0x83'), hex.to_dec('0xad'))
print(string.len(byte_3))
utf8.utf_to_uni(byte_3)
--]]
--[[
byte_2 = string.format('%c%c', hex.to_dec('0xC2'), hex.to_dec('0x9D'))
utf8.utf_to_uni(byte_2)
byte_1 = string.format('%c', hex.to_dec('0xB'))
utf8.utf_to_uni(byte_1)
--]]
--[[
test_mul = string.format(
'%c%c%c%c%c%c%c%c%c',
hex.to_dec('0xE8'),hex.to_dec('0xAF'), hex.to_dec('0xBA'),
hex.to_dec('0xE5'),hex.to_dec('0x9F'), hex.to_dec('0xBA'),
hex.to_dec('0xE4'),hex.to_dec('0xBA'), hex.to_dec('0x9A'))
utf8.print_hex(utf8.utf_to_uni(test_mul))
--]]