unity ngui中utf8非法字符串检查以及过滤Emoji表情源码Unity

/ / 2015-10-25
有些UI组件并不支持显示Emoji,甚至会在显示的时候导致崩溃,以下是我在我们项目中,使用NGUI的UILabel时候,对Emoji做的处理 //用于过滤Emoji表情,以及字节流中非法的utf8字节流 //Emoji表情基于Unicode 8.0标准 https://en.wikipedia.org/wiki/Emoji //主...

有些UI组件并不支持显示Emoji,甚至会在显示的时候导致崩溃,以下是我在我们项目中,使用NGUI的UILabel时候,对Emoji做的处理

//用于过滤Emoji表情,以及字节流中非法的utf8字节流

//Emoji表情基于Unicode 8.0标准 https://en.wikipedia.org/wiki/Emoji

//主要过滤掉了四字节的utf8字节流(因为有很大一部分Emoji在Utf8的编码中都是4个字节,大部分汉字都在三字节,对于没有特殊文本显示要求的,可以这样来做),以及部分已公布的三字节utf8 Emoji字节流

//这里面过滤的并不完全,还有一些并没包含在里面,最新公布的共有1051个Emoji


//utf8 code page head
	static Byte[] cov_map_from_utf8 = {
				0x00,       // 0xxxxxxx
				0xc0,       // 110xxxxx
				0xe0,       // 1110xxxx
				0xf0,       // 11110xxx
				0xf8,       // 111110xx
				0xfc        // 1111110x
			};
//https://en.wikipedia.org/wiki/Emoji
	//range U2700–U27BF
	static int minEmoji1 = 0xE29C80;		//0x2700 --> 11100010	10 011100	10 000000
	static int maxEmoji1 = 0xE29EBF;		//0x27BF --> 11100010   10 011110	10 111111
//range U2600–U26FF
	static int minEmoji2 = 0xE29880;	   //0x2600 -->  11100010   10 011000   10 000000
	static int maxEmoji2 = 0xE29BBF;	   //0x26FF -->  11100010   10 011011   10 111111
//param: utf8Bytes ,source utf8bytes
	//       checkEmoji,
	//       CheckValu , after check and filter,the target utf8 bytes
	static bool CheckAndFilterUtf8bytes(Byte[] utf8Bytes, bool checkEmoji, out Byte[] CheckValue)
	{
		CheckValue = null;
		ArrayList target = new ArrayList();
		int count = utf8Bytes.Length;
		for (int j = 0; j < count; )
		{
			int size = 0;
			if (!CheckUtf8CodeLenth(utf8Bytes[j], out size))
			{
				//invalid utf8 stream
				return false;
			}
			if (checkEmoji)
			{
				if (size < 4 && count >= j + size)
				{
					bool isEmoji = false;
					if (size == 3)
					{
						//check emoji range
						int checkvalue = (utf8Bytes[j] << 16 ) + (utf8Bytes[j + 1] << 8) + utf8Bytes[j + 2];
						if ((checkvalue > minEmoji1 && checkvalue < maxEmoji1) || (checkvalue > minEmoji2 && checkvalue < maxEmoji2))
						{
							isEmoji = true;
						}
					}
					if (!isEmoji)
					{
						for (int k = 0; k < size; ++k)
						{
							target.Add(utf8Bytes[k + j]);
						}
					}
				}
				else
				{
					//ignore the utf8 bytes code which length beyond 3;
				}
			}
			j += size;
		}
		if (!checkEmoji)
        {
            CheckValue = utf8Bytes;
        }
        else
        {
            CheckValue = (Byte[])target.ToArray(typeof(Byte));
        }
		return true;
	}
static bool CheckUtf8CodeLenth(Byte from, out int size)
	{
		size = 6;
		for (int i = size - 1; i >= 0; --i)
		{
			Byte c = cov_map_from_utf8[i];
			int ct = from & c;
			if (c == ct)
			{
				return true;
			}
			--size;
		}
		return false;
	}

CheckUtf8CodeLenth用来检查utf8字节流的长度,因为utf8编码变长特性,可以根据第一个字节的编码,来决定后面几个字节是一组编码,所以也可以用来检查字节流的有效性

1