微信机器人无法踢人的小Bug

问题描述

昨天遇到一个比较好玩的问题,微信群的管理反馈只要群昵称带有🌺的均踢不掉。今天查到了发现是因为微信在下发群成员数据的时候会随机的下发下面两种格式的群员昵称。

第一种(emoji表情转换成UTF-8显示)

'\xe6\x89\x93\xe9\x85\xb1\xe6\xb2\xb9\xe6\xbb\xb4\xe5\xad\xa9\xe7\xba\xb8\xf0\x9f\x8c\xba'

第二种(emoji表情未转换,还是以HTML标签的形式标识的)

'\xe6\x89\x93\xe9\x85\xb1\xe6\xb2\xb9\xe6\xbb\xb4\xe5\xad\xa9\xe7\xba\xb8<span class="emoji emoji1f33a"></span>'

而收到的踢人命令是这样的:

打酱油滴孩纸🌺 飞机票

转换成UTF-8显示就是上面第二种的原始编码,所以无法踢人的原因就是机器人收到以第二种的形式编码的踢人命令,而本地保存的群员数据却是以第一种形式保存的,导致不匹配,自然就找不到群员踢不掉了。

如何解决问题

我们仔细观察第一种和第二种的编码主要的区别在于

\xf0\x9f\x8c\xba
<span class="emoji emoji1f33a"></span>

聪明的人应该可以想到了,1f33a 是的🌺的unicode标识,而 \xf0\x9f\x8c\xba 其实就是🌺的UTF-8编码。

具体可以看emoji编码表 Unicode character inspector: 🌺

所以需要解决的问题就转化成已知 unicode值1f33a,如何求得其UTF-8的编码值,求解源码如下所示,具体就不解释了。

#coding: utf-8
import re
data = '\xe6\x89\x93\xe9\x85\xb1\xe6\xb2\xb9\xe6\xbb\xb4\xe5\xad\xa9\xe7\xba\xb8<span class="emoji emoji1f33a"></span> 飞机票'
[remove_user, remove_str] = data.rsplit(' ', 1)
print remove_user
print remove_str
matches = re.findall(r"<span.+?<\/span>", remove_user)
for item in matches:
emoji_unicode = re.findall(r"emoji([\w\d]*?)\"", item)
print emoji_unicode
emoji_int = int(emoji_unicode[0], 16)
s = "\\U%08x" % emoji_int
c = s.decode('unicode-escape')
d = c.encode('utf-8')
data = data.replace(item, d)
print list(data)