[原]涂鸦板oekakibbs和Shi-PainterPRO数据格式分析
Posted by bianbian on 2006-12-19 06:33
去年用C语言实现的涂鸦板:http://bbs.nju.edu.cn/pntmain
想当年,一夜没睡,不停地debug、截获网络数据,分析涂鸦板oekakibbs和Shi-PainterPRO的数据格式。
最后保存成功带给我的喜悦我是终身难忘。这也是我喜欢编程的部分原因吧。呵呵
oekakibbs和Shi-PainterPRO是比较有名的涂鸦板程序(实际是Java Applet程序),通过http协议和自定义的数据格式往后台提交数据。解析数据网络上比较多的是php和asp的代码,但是因为和彼此自己的系统结合,所以看起来比较费尽。不过从来没有数据格式说明文档。
今天偶然又翻了一下这些代码,顺便在blog里记一下。要是能给其他人省点力气,也算功德一件。呵呵
- /*
- 解析涂鸦板传过来的数据并保存图片
- Net@Lilybbs, 2005-11-14 7:18
- /////////////////////////////
- 参数传递:pntupload?临时key_工具名
- ====================================
- oekakibbs数据格式:
- -------------------------------
- ...Content-type:string
- Content-type:string
- Content-type:image/0
- {PNG图片数据}
- Content-type:animation/
- {oekakibbs动画数据}
- ====================================
- Shi-PainterPRO数据格式:
- -------------------------------
- S0000000000{当前PNG图片的字节数}
- {PNG图片数据}{pch长度}{pch文件内容}
- -------------------------------
- //以下是pch文件内容:
- layer_count=3
- layer_max=35
- layer_last=35
- image_width=300
- image_height=300
- count_lines=25
- quality=1
- {其他信息}
- -------------------------------
- */
- #include "www.h"
- int pntupload_main()
- {
- int n, i, j, key=0;
- char tmp[80], *buf, tool[30], *p;
- FILE *fp;
- chdir(BBSHOME);
- http_header(200);
- printf("Content-type: text/html; charset=gb2312\n\n");
- n = atoi(getsenv("CONTENT_LENGTH"));
- if (n<0 || n>3000000)
- http_fatal("too big");
- buf = malloc(n);
- if(buf==0) http_fatal("out of memory");
- fread(buf, 1, n, stdin); //读入buf
- /*
- fp = fopen("paint/data", "w");
- fwrite(buf, 1, n, fp);
- fclose(fp);
- */
- //-------- 获得_U_KEY
- key = atoi(getsenv("QUERY_STRING"));
- //-------- 获得tool
- p = strchr(getsenv("QUERY_STRING"), '_');
- strsncpy(tool, p+1, 20);
- //-------- 根据不同tool, 不同处理数据
- //oekakibbs和oekakibbs2的处理是一样的
- if(!strncmp("oekakibbs", tool, 9))
- {
- //-------- 获得图片
- i = memstr(buf, n, "Content-type:image/0");
- j = memstr(buf+i+24, n, "Content-type:animation/"); //24是"Content-type:image/0\r\n\r\n"的长度
- sprintf(tmp, "paint/tmp/%d.png", key);
- fp = fopen(tmp, "w");
- fwrite(buf + i + 24, 1, j, fp); //j实际是png的长度
- fclose(fp);
- //-------- 获得动画
- j += i+24; //j现在是从buf开始指向Content-type:animation的偏移量
- sprintf(tmp, "paint/tmp/%d.oeb", key);
- fp = fopen(tmp, "w");
- fwrite(buf+j+27, 1, n - j - 27, fp); //p2-buf是长度,27是"Content-type:animation/\r\n\r\n"的长度
- fclose(fp);
- //需要输出success告诉applet保存成功
- printf("success");
- }
- else if(!strcmp("Shi-Painter", tool))
- {
- //png 头:HEX 89 50 4E 47 0D 0A
- //png 尾:HEX 49 45 4E 44 AE 42 60 82
- //unsigned char pngend[] = {0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82};
- i = memstr(buf, n, "\r\n"); //第2行开始就是PNG图片
- j = atoi(buf+1); //buf[0]固定是S,之后就是PNG的长度
- sprintf(tmp, "paint/tmp/%d.png", key);
- fp = fopen(tmp, "w");
- fwrite(buf+i+2, 1, j, fp);
- fclose(fp);
- //-------- 获得动画
- j += i+2; //j现在是从buf开始指向PNG末尾的偏移量
- i = memstr(buf+j, n, "layer_count="); //这里的i就相当于oekakibbs里面的27:就是PNG末尾到layer_count的长度
- sprintf(tmp, "paint/tmp/%d.oeb", key);
- fp = fopen(tmp, "w");
- fwrite(buf+j+i, 1, n-j-i, fp);
- fclose(fp);
- }
- exit(0);
- }
遵守创作共用协议,转载请链接形式注明来自http://bianbian.org 做人要厚道