function lzwCode(szSource, nBeginCode)
	local tbOutput = {}
	local tbChar = {}
	local szPrefix = ""
	local tbToken = {}
	local nTokenCode = nBeginCode
	for szChar in string.gmatch(szSource, ".") do
		tbChar[szChar] = true
		if szPrefix == "" then
			szPrefix = szChar
		else
			if tbToken[szPrefix .. szChar] then
				szPrefix = tbToken[szPrefix .. szChar]
			else
				tbToken[szPrefix .. szChar] = nTokenCode
				nTokenCode = nTokenCode + 1
				table.insert(tbOutput, szPrefix)
				szPrefix = szChar
			end
		end
	end
	if szPrefix~= "" then
		table.insert(tbOutput, szPrefix)
	end
	return tbOutput, tbChar
end

function lzwFindFirstNormalChar(tbDeCodeToken, szCode)
	local szNormalChar = szCode
	while (tbDeCodeToken[tonumber(szNormalChar)]) do
		szNormalChar = tbDeCodeToken[tonumber(szNormalChar)][1]
	end
	return szNormalChar
end

function lzwDecodeToSource(szSource, tbDeCodeToken, szPrefix)
	local tbPrefix = { szPrefix }
	while #tbPrefix ~= 0 do
		local szFirst = table.remove(tbPrefix, 1)
		local tbDecode = tbDeCodeToken[tonumber(szFirst)]
		if tbDecode then
			table.insert(tbPrefix, 1, tbDecode[2])
			table.insert(tbPrefix, 1, tbDecode[1])
		else
			szSource = szSource .. szFirst
		end
	end
	return szSource
end

function lzwDecode(tbCode, tbChar, nBeginCode)
	local szSource = ""
	local szPrefix = ""
	local tbToken = {}
	local tbDeCodeToken = {}
	local nTokenCode = nBeginCode
	for _, szCode in ipairs(tbCode) do
		if szPrefix ~= "" then
			if tbChar[szCode] then	--判断后缀是否是正常后缀
				tbToken[szPrefix .. szCode] = nTokenCode
				tbDeCodeToken[nTokenCode] = { szPrefix, szCode }
				nTokenCode = nTokenCode + 1
				--前缀放入输出流
				szSource = lzwDecodeToSource(szSource, tbDeCodeToken, szPrefix)
			else
				if tbDeCodeToken[tonumber(szCode)] then
					local szSuffix = lzwFindFirstNormalChar(tbDeCodeToken, tbDeCodeToken[tonumber(szCode)][1])
					tbToken[szPrefix .. szSuffix] = nTokenCode
					tbDeCodeToken[nTokenCode] = { szPrefix, szSuffix }
					nTokenCode = nTokenCode + 1
					--前缀放入输出流
					szSource = lzwDecodeToSource(szSource, tbDeCodeToken, szPrefix)
				else
					if tbChar[szPrefix] then
						tbToken[szPrefix .. szPrefix] = nTokenCode
						tbDeCodeToken[nTokenCode] = { szPrefix, szPrefix }
					else
						local szSuffix = lzwFindFirstNormalChar(tbDeCodeToken, tbDeCodeToken[tonumber(szPrefix)][1])
						tbToken[szPrefix .. szSuffix] = nTokenCode
						tbDeCodeToken[nTokenCode] = { szPrefix, szSuffix }
					end
					nTokenCode = nTokenCode + 1
					--前缀放入输出流
					szSource = lzwDecodeToSource(szSource, tbDeCodeToken, szPrefix)
				end
			end
		end
		szPrefix = szCode
	end
	szSource = lzwDecodeToSource(szSource, tbDeCodeToken, szPrefix)
	return szSource
end

--[[字符串测试
local szSource = "dsfakfjljsds  sdf\ \tfg\\ \ "
local nBeginCode = 6
print(szSource)
local tbCode, tbChar = lzwCode(szSource, nBeginCode)
print(table.concat(tbCode, ","))
print(lzwDecode(tbCode, tbChar, nBeginCode))
]]

--[[文件测试
local hFile = io.open("1.txt", "r")
local szStr = hFile:read("*a")
print("origin length = ", string.len(szStr))
local tbCode, tbChar = lzwCode(szStr, 6)
local hOutputFile = io.open("2.txt", "w")
hOutputFile:write(table.concat(tbCode, ","))
print("output length = ", #tbCode)
local hDecodeFile = io.open("3.txt", "w")
hDecodeFile:write(lzwDecode(tbCode, tbChar, 6))
]]