sunmoon1997 发表于 2004-9-22 16:39:10

QQ自定义表情分析 ^_^

下面是一串字符:
7824DB6EEF67565E1CD67023CA2E69FB
还有一个文件在附件里。
谁能想办法从那个文件得到这个字符串吗?可能需要md5sum之类的。
另外可能与其相关的是字符2,注意不是数字。
附件的md5sum是:
d468933b95a1d0845737537277dfcb58
但更可能的是与其md5sum的大写相关,即
D468933B95A1D0845737537277DFCB58。
各位狼狼试试吧,帮我一起找出其中的规律吧。。。
或者还有其它的方法。。。

llc 发表于 2004-9-22 16:43:39

帮顶

yeee 发表于 2004-9-22 16:44:15

帮顶。
巨讨厌猜谜

sunmoon1997 发表于 2004-9-22 16:49:00

这不是猜谜,,这是QQ加密出来的东西。。
当有字符1时,那一串字符就是md5sum的大写,
而是2时,情况就不一样了,肯定是做了什么手脚。。 :twisted::twisted:

llc 发表于 2004-9-22 16:54:28

这不是猜谜,,这是QQ加密出来的东西。。
当有字符1时,那一串字符就是md5sum的大写,
而是2时,情况就不一样了,肯定是做了什么手脚。。 :twisted::twisted:
找openq看代码不行吗?还没支持的功能?

sunmoon1997 发表于 2004-9-22 16:56:15

要支持就不会在这里问了。。。

jiangtao9999 发表于 2004-9-22 17:06:27

那个 7824DB6EEF67565E1CD67023CA2E69FB 是加密那个文件的密码?
经过特殊运算了?

sunmoon1997 发表于 2004-9-22 17:25:50

终于清楚了,呵呵,原来QQ会把bmp图片转化为jpg,所以md5sum就会变,而我还是
用原来的bmp图片算的md5sum,所以就会不一样,与那个2也没有什么关系,字符1,2
具体含义还是个未知数,无法得知其用途。
这是QQ发自定义表情出来的一串字符,狼狼们,你们知道是什么意思不?
0x15327824DB6EEF67565E1CD67023CA2E69FB.JPGB5
除了第一个字符是十六进制(0x15), 其它的都是字符,呵呵。。。

sunmoon1997 发表于 2004-9-22 17:26:46

终于被偶破解了。。。

xhdwh 发表于 2004-9-22 17:50:04

终于被偶破解了。。。



故意卖弄风骚:mrgreen:

sunmoon1997 发表于 2004-9-22 18:05:17

终于被偶破解了。。。



故意卖弄风骚:mrgreen:
:twisted::twisted::twisted:
我什么地方惹你了。。。。

lovewilliam 发表于 2004-9-22 21:00:24

终于被偶破解了。。。

GPL

GPL :mrgreen:

llc 发表于 2004-9-22 21:01:53

终于被偶破解了。。。

GPL

GPL :mrgreen:
能详细点就更好

lanche 发表于 2004-9-22 21:12:19

帖出来大家GPL之。

sunmoon1997 发表于 2004-9-22 22:08:32

const gchar *QQ_SPT_IMG_EXT[] ={".BMP", ".GIF", ".JPEG", ".JPG", NULL};
#define QQ_USERDEFINED_SMILEY_FLAGS "\025"
#define MSG_FILTER_PROM   "[X]"
#define MSG_FILTER_PROM_SIZE(sizeof(MSG_FILTER_PROM) - 1) //donnot include the terminal char
#define QQ_SMILEY_SHOTCUT_MAX(6)
//包含QQ自定义表情的文本至少得39个字节, 2字节操作符,32字节md5,4个字节扩展名,
//1字节快捷方式长度,快捷方式可以没有
#define QQ_USERDEINED_SMILEY_MIN_LEN (39)
                                          

/***********************************************************************************
                md5sum                   ____   _____
(\x15)32FE05FF7FDBE0CF68CB2A108F7B8D5B48.GIFDabc(\x15)4A
______^^________________________________    ^___      ^^
前导字符是0x15,可能代表QQ中与文件有关的一类操作
在0x15后面,还有一个操作符,‘3’和‘4'是与自定义表情有关的
另外还有‘2’等,‘2'与文件传送有关。'3'代表QQ自定义表情在
当前对话中第一次出现,'4'代表表情已经在当前对话中现过,如果
出现的是\x153则后面还有一个字符一般为'1'或者'2',意义未知.
紧接着是表情文件的32字节md5码,这个唯一的决定了QQ的自定义表情,
然后是自定义表情的扩展名,QQ支持的有四种.BMP,GIF,.JPEG,
.JPG.最后是与表情快捷方式有关的部分了, 第1个字节代表着表情
快捷方式的长度,实际长度等于其值减去'A', 但不得超过6个字节.
再后面就是快捷方式的实际内容了.而出现\x154的话就是要重复
前面已存在的表情如果后面是字符'A'的话,就用第一个表情代替,
'B'就第二个,依此类推即可.

当前还无法与QQ互传文件只能先过滤掉这么乱码,留下有用信息。
*/

/************************************************************************************
@param text 等待过滤的文本
@param maintain_shotcut 是否保留快捷方式 TRUE 保留 FALSE 不保留

@return 过滤后的文本 注意:这个文本需要调用者释放否则就会内存泄露
*/

gchar *qq_im_filter_userdefined_smiley(const gchar *text, gboolean maintain_shotcut) {
GString        *converted;
gchar                *begin, *end, *cnt, **smiley_ex_flags, *result;
static gchar        shotcuts[26][QQ_SMILEY_SHOTCUT_MAX + 1]; //define as static to speedup
gint                last_shotcut = -1, shotcut_len = 0;

//没有0x15,或者文本长度小于39,则不可能包含QQ自定义表情,直接返回。
if (!g_strstr_len(text, -1, QQ_USERDEFINED_SMILEY_FLAGS) || strlen(text) < QQ_USERDEINED_SMILEY_MIN_LEN)
        return NULL;

converted = g_string_new(text);

if (!converted)
      return NULL;
      
begin = cnt = converted->str;

gaim_debug(GAIM_DEBUG_INFO, "QQ_ORIG_MESG", "%s.\n", begin);

while (cnt && *cnt) {
        cnt = g_strstr_len(cnt, -1, QQ_USERDEFINED_SMILEY_FLAGS);
      if (!cnt || !(*(cnt +1))) {
           break;
        }
       
        //第2个操作符必须是数字
        if (!g_ascii_isdigit(cnt[1])) {
          cnt ++;
          continue;
        }
       
        //此次对话中还没有出现过的QQ自定义表情
        if ( cnt[1] == '3') {
                //skip some chars
                //____ _<-unknown
                //\x1532FE05FF7FDBE0CF68CB2A108F7B8D5B48.GIFDabc
                //^<-cnt                              ^<-end
                end = cnt + 1 + 1 + 32 + 1;
               
                //out of the text bound
                if(end >= begin + converted->len)
                  break;
               
                //now check smiley extension name, .BMP, .GIF, .JPEG, .JPG
                for (smiley_ex_flags = (gchar **)QQ_SPT_IMG_EXT; smiley_ex_flags != NULL && *smiley_ex_flags != '\0'; smiley_ex_flags++) {
                        if(!g_ascii_strncasecmp(end, *smiley_ex_flags, strlen(*smiley_ex_flags))) {
                                end += strlen(*smiley_ex_flags);
                                break;
                        }
                }
               
                // the expected smiley extension name is found
                if (smiley_ex_flags != NULL && *smiley_ex_flags != '\0') {
                        if (*end ) {
                                //         extension name of smiley --> ____
                                //\x1532FE05FF7FDBE0CF68CB2A108F7B8D5B48.GIFDabc
                                //            shotcut length('D'-'A' = 3)-> ^--- <-shotcut of smiley
                                shotcut_len = *end - 'A';
                                if (maintain_shotcut == FALSE && (*end >= 'A') && (shotcut_len <= QQ_SMILEY_SHOTCUT_MAX)
                                  && (end + (shotcut_len)<= begin + converted->len)) {
                                        if((!end[shotcut_len] && end + shotcut_len - cnt - 1 >= MSG_FILTER_PROM_SIZE) ||
                                           ( end[shotcut_len] && end + shotcut_len - cnt >= MSG_FILTER_PROM_SIZE)) {      
                                                g_strlcpy(cnt,MSG_FILTER_PROM, MSG_FILTER_PROM_SIZE);//tell user we filter some msg.
                                                cnt += MSG_FILTER_PROM_SIZE;
                                        }
                                       
                                        //store the shotcut
                                        if ( last_shotcut < 25) {
                                        // donnot need copy the shotcut
                                        //        g_strlcpy(shotcuts[++last_shotcut], end + 1 , end[0] - 'A');
                                        //        shotcuts[last_shotcut][end[0] - 'A'] = '\0';
                                                ++last_shotcut;
                                        }
                                       
                                        end += (end[0] - 'A') + 1;
                                }
                                else        { //maintain the shotcut
                                        //store the shotcut
                                        if ( last_shotcut < 25 && (*end >= 'A') && shotcut_len <= QQ_SMILEY_SHOTCUT_MAX) {
                                                g_strlcpy(shotcuts[++last_shotcut], end + 1 , shotcut_len);
                                                shotcuts[last_shotcut][shotcut_len] = '\0';
                                        }
                                        end ++;
                                }
                        }
                       
                        g_string_erase(converted, (cnt - begin), (end - cnt));
                       
                        if (maintain_shotcut && last_shotcut < 25 ) //skip shotcuts
                                cnt += shotcut_len;
                        continue;
                }
                else {
                        //\x153...
                        // ^-> ^
                        //bad string, skip...
                        cnt += 2;
                        continue;
                }
        }
        else if (cnt[1] == '4' ) {
                if (maintain_shotcut == FALSE) {
                        if (cnt[2] >= 'A' && cnt[2] <= 'Z' && cnt[2] - 'A' <= last_shotcut) {//\x154[A-Z]
                                gint left_size = 3;
                                if( 3 >= MSG_FILTER_PROM_SIZE) {
                                        g_strlcpy(cnt,MSG_FILTER_PROM, MSG_FILTER_PROM_SIZE);//tell user we filter some msg.
                                        cnt += MSG_FILTER_PROM_SIZE;
                                        left_size -= MSG_FILTER_PROM_SIZE;
                                }
                                g_string_erase(converted, (cnt - begin), left_size); //erase left chars
                        }
                        else cnt ++;
                }
                else {
                        if (cnt[2] >= 'A' && cnt[2] <= 'Z' && last_shotcut >= 0) { //\x154[A-Z]
                                shotcut_len = strlen(shotcuts[cnt[2] - 'A']);

                                if (shotcut_len > 0 && shotcut_len <= 3 && cnt[2] - 'A' <= last_shotcut) {
                                        g_strlcpy(cnt, shotcuts[cnt[2] - 'A'], shotcut_len);
                                        cnt += shotcut_len;
                                        if (shotcut_len < 3) {
                                                g_string_erase(converted, (cnt - begin), 3 - shotcut_len);
                                        }
                                }
                                else {
                                        g_string_erase(converted, (cnt - begin), 3);
                                }
                        }
                }
                continue;
}
cnt ++;
}

gaim_debug(GAIM_DEBUG_INFO, "QQ_FILTERED_MESG", "%s.\n", begin);

result = converted->str;
g_string_free(converted, FALSE);

if (last_shotcut >= 0 && maintain_shotcut == TRUE) //clear the buffer
   memset(&shotcuts[0][0], sizeof(shotcuts), 0);

return result;
}//qq_im_filter_userdefined_smiley
页: [1] 2
查看完整版本: QQ自定义表情分析 ^_^