c++encode http请求带中文参数
2015-08-24 10:38
716 查看
我们前端是C++的,服务器是java的,传输的数据需要encode编码和decode解码。碰到的问题就是http网络请求带中文参数时(我们传的是玩家姓名),服务器接到的参数和我传过去的是不一致的。这就需要处理带中文参数的问题。
前端传过去的:content=eyJ1aWQiOiJsYWxhMTEiLCJnYW1laWQiOiIxMDAxIiwicGxheWVybmFtZSI6IumrmOWkp+Wco+iQveiQvSIsInBsYXllcnNleCI6MCwicGxheWVyaW1hZ2UiOjEwMDR9&sign=ff595ba32a2dd04d8344cf5d86788293
服务器收到的:content====eyJ1aWQiOiJsYWxhMTEiLCJnYW1laWQiOiIxMDAxIiwicGxheWVybmFtZSI6IumrmOWkp Wco iQveiQvSIsInBsYXllcnNleCI6MCwicGxheWVyaW1hZ2UiOjEwMDR9
+变成了空格。
java那边可以在传的时候加上编码格式:String encodeAfter = URLEncoder.encode(“conteng”, "utf-8");但是c++里没有这个方法。于是在网上找了一下,发现有可以支持不管带不带中文都可以的encode代码。但是这样编码之后是这样的%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D,服务器那边说解析不了,于是我就在java上新建个测试类,代码如下:
String test = "{\"uid\":\"lala11\",\"gameid\":\"1001\",\"playername\":\"开心的笑笑\",\"playersex\":0,\"playerimage\":1005}";
System.out.println("test:"+test);
try {
String encodeAfter = URLEncoder.encode(test, "utf-8");//utf-8"
System.out.println("encodeAfter:"+encodeAfter);
String test1 = "%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D";
String decodeAfter = URLDecoder.decode(test1, "utf-8");//utf-8"
System.out.println("test1:"+test1);
System.out.println("decodeAfter:"+decodeAfter);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
经测试通过URLEncoder.encode(test, "utf-8");//utf-8"编码后也是%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D格式的,并且通过URLDecoder.decode(test1, "utf-8");//utf-8"解码后是完全正确的信息。
后来才发现服务器在解码的时候没用URLDecoder.decode(test1, "utf-8");//utf-8",也是醉了..
好,总结一下就是:C++用新的encode和decode代码,让服务器用URLDecoder.decode(test1, "utf-8");来解码,若需要MD5对比内容,服务器也需用URLEncoder.encode(test, "utf-8");//utf-8"来编码。
C++端的encode和decode代码如下:
.h:
#include <assert.h>
////////////////////解决传输中文问题的编码///////////////////////////////////
static const char safe[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
std::string encode(const std::string &uri);
std::string decode(const std::string &uri);
.cpp:
#include <iostream>
using namespace std;
std::string encode(const std::string &uri)
{
string ret;
const unsigned char *ptr = (const unsigned char *)uri.c_str();
ret.reserve(uri.length());
for (; *ptr ; ++ptr)
{
if (!safe[*ptr])
{
char buf[5];
memset(buf, 0, 5);
#ifdef WIN32
_snprintf_s(buf, 5, "%%%X", (*ptr));
#else
snprintf(buf, 5, "%%%X", (*ptr));
#endif
ret.append(buf);
}
else if (*ptr==' ')
{
ret+='+';
}
else{
ret += *ptr;
}
}
return ret;
}
std::string decode(const std::string &uri)
{
//Note from RFC1630: "Sequences which start with a percent sign
//but are not followed by two hexadecimal characters (0-9,A-F) are reserved
//for future extension"
const unsigned char *ptr = (const unsigned char *)uri.c_str();
string ret;
ret.reserve(uri.length());
for (; *ptr; ++ptr)
{
if (*ptr == '%')
{
if (*(ptr + 1))
{
char a = *(ptr + 1);
char b = *(ptr + 2);
if (!((a >= 0x30 && a < 0x40) || (a >= 0x41 && a < 0x47))) continue;
if (!((b >= 0x30 && b < 0x40) || (b >= 0x41 && b < 0x47))) continue;
char buf[3];
buf[0] = a;
buf[1] = b;
buf[2] = 0;
ret += (char)strtoul(buf, NULL, 16);
ptr += 2;
continue;
}
}
if (*ptr=='+')
{
ret+=' ';
continue;
}
ret += *ptr;
}
return ret;
}
前端传过去的:content=eyJ1aWQiOiJsYWxhMTEiLCJnYW1laWQiOiIxMDAxIiwicGxheWVybmFtZSI6IumrmOWkp+Wco+iQveiQvSIsInBsYXllcnNleCI6MCwicGxheWVyaW1hZ2UiOjEwMDR9&sign=ff595ba32a2dd04d8344cf5d86788293
服务器收到的:content====eyJ1aWQiOiJsYWxhMTEiLCJnYW1laWQiOiIxMDAxIiwicGxheWVybmFtZSI6IumrmOWkp Wco iQveiQvSIsInBsYXllcnNleCI6MCwicGxheWVyaW1hZ2UiOjEwMDR9
+变成了空格。
java那边可以在传的时候加上编码格式:String encodeAfter = URLEncoder.encode(“conteng”, "utf-8");但是c++里没有这个方法。于是在网上找了一下,发现有可以支持不管带不带中文都可以的encode代码。但是这样编码之后是这样的%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D,服务器那边说解析不了,于是我就在java上新建个测试类,代码如下:
String test = "{\"uid\":\"lala11\",\"gameid\":\"1001\",\"playername\":\"开心的笑笑\",\"playersex\":0,\"playerimage\":1005}";
System.out.println("test:"+test);
try {
String encodeAfter = URLEncoder.encode(test, "utf-8");//utf-8"
System.out.println("encodeAfter:"+encodeAfter);
String test1 = "%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D";
String decodeAfter = URLDecoder.decode(test1, "utf-8");//utf-8"
System.out.println("test1:"+test1);
System.out.println("decodeAfter:"+decodeAfter);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
经测试通过URLEncoder.encode(test, "utf-8");//utf-8"编码后也是%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D格式的,并且通过URLDecoder.decode(test1, "utf-8");//utf-8"解码后是完全正确的信息。
后来才发现服务器在解码的时候没用URLDecoder.decode(test1, "utf-8");//utf-8",也是醉了..
好,总结一下就是:C++用新的encode和decode代码,让服务器用URLDecoder.decode(test1, "utf-8");来解码,若需要MD5对比内容,服务器也需用URLEncoder.encode(test, "utf-8");//utf-8"来编码。
C++端的encode和decode代码如下:
.h:
#include <assert.h>
////////////////////解决传输中文问题的编码///////////////////////////////////
static const char safe[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
std::string encode(const std::string &uri);
std::string decode(const std::string &uri);
.cpp:
#include <iostream>
using namespace std;
std::string encode(const std::string &uri)
{
string ret;
const unsigned char *ptr = (const unsigned char *)uri.c_str();
ret.reserve(uri.length());
for (; *ptr ; ++ptr)
{
if (!safe[*ptr])
{
char buf[5];
memset(buf, 0, 5);
#ifdef WIN32
_snprintf_s(buf, 5, "%%%X", (*ptr));
#else
snprintf(buf, 5, "%%%X", (*ptr));
#endif
ret.append(buf);
}
else if (*ptr==' ')
{
ret+='+';
}
else{
ret += *ptr;
}
}
return ret;
}
std::string decode(const std::string &uri)
{
//Note from RFC1630: "Sequences which start with a percent sign
//but are not followed by two hexadecimal characters (0-9,A-F) are reserved
//for future extension"
const unsigned char *ptr = (const unsigned char *)uri.c_str();
string ret;
ret.reserve(uri.length());
for (; *ptr; ++ptr)
{
if (*ptr == '%')
{
if (*(ptr + 1))
{
char a = *(ptr + 1);
char b = *(ptr + 2);
if (!((a >= 0x30 && a < 0x40) || (a >= 0x41 && a < 0x47))) continue;
if (!((b >= 0x30 && b < 0x40) || (b >= 0x41 && b < 0x47))) continue;
char buf[3];
buf[0] = a;
buf[1] = b;
buf[2] = 0;
ret += (char)strtoul(buf, NULL, 16);
ptr += 2;
continue;
}
}
if (*ptr=='+')
{
ret+=' ';
continue;
}
ret += *ptr;
}
return ret;
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- RPC failed; result=22, HTTP code = 411
- 关于指针的一些事情
- Java 6 JVM参数选项大全(中文版)
- HTTP Header 属性列表
- nginx中http核心模块的配置指令2
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- autoit 命令行参数说明
- 给IE加个参数 永远不怕IE主页被修改
- 深入HTTP head的使用详解
- C#读取中文文件出现乱码的解决方法
- ASP 中使用 HTTP 协议发送参数详解
- C#基于socket模拟http请求的方法
- http www安全必备知识
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- 写批处理必备的一些命令参数使用技巧