PPP数据成帧转义,C语言实现
#include <stdio.h>
#include <string.h>
// PPP数据帧每一帧都以标识字符0x7E开始和结束;
// 由于标识字符的值是0x7E,因此当该字符出现在信息字段中时,PPP需要对它进行转义。
// 当PPP使用异步传输时,它把转义字符定义为:0x7D,并使用字节填充RFC-1662标准。
// 字节填充RFC-1662标准规定如下:
// 1. 把信息字段中出现的每一个0x7E字符转变成字节序列(0x7D,0x5E)
// 2. 若信息字段中出现一个0x7D的字节(即出现了与转义字符相同的比特组合),
// 则把0x7D转义成两个字节序列(0x7D,0x5D)
// 3. 若信息字段中出现ASCII码的控制字符(即数值小于0x20的字符),
// 则在该字符前面加入一个0x7D字节,同时将该字符的编码加以改变
#define PPP_FRAME_FLAG ( 0x7E ) /* 标识字符 */
#define PPP_FRAME_ESC ( 0x7D ) /* 转义字符 */
#define PPP_FRAME_ENC ( 0x20 ) /* 编码字符 */
int ppp_encode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
{
unsigned char *pi, *po;
int i, tmp_len;
pi = in;
po = out;
tmp_len = in_len;
for(i = 0; i < in_len; i++)
{
if( *pi == PPP_FRAME_FLAG || *pi == PPP_FRAME_ESC || *pi < 0x20 )
{
*po = PPP_FRAME_ESC;
po++;
tmp_len++;
*po = *pi ^ PPP_FRAME_ENC;
}
else
{
*po = *pi;
}
pi++;
po++;
}
*out_len = tmp_len;
return 0;
}
int ppp_decode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
{
unsigned char *pi, *po;
int i, tmp_len;
pi = in;
po = out;
tmp_len = in_len;
for(i = 0; i < in_len; i++)
{
if(*pi == PPP_FRAME_ESC)
{
pi++;
tmp_len--;
*po = *pi ^ PPP_FRAME_ENC;
i++;
}
else
{
*po = *pi;
}
pi++;
po++;
}
*out_len = tmp_len;
return 0;
}
void printf_hex(char *title, unsigned char *hex, int n)
{
int i;
printf("%s", title);
for(i = 0; i < n; i++)
{
if(i % 16 == 0 && i != 0)
printf("\r\n");
printf("%02x ", (unsigned char )hex[i]);
}
printf("\r\n");
}
int main(void)
{
unsigned char p1[256];
unsigned char p2[512];
unsigned char p3[512];
int i, len1, len2, len3;
len1 = sizeof(p1)/sizeof(p1[0]);
for(i = 0; i < len1; i++)
{
p1[i] = i % 256;
}
printf_hex("Before Encode::\r\n", p1, len1);
printf("Before Encode, len1: %d\r\n", len1);
ppp_encode(p1, len1, p2, &len2);
printf_hex("After Encode::\r\n", p2, len2);
printf("After Encode, len2: %d\r\n", len2);
ppp_decode(p2, len2, p3, &len3);
printf_hex("After Decode::\r\n", p3, len3);
printf("After Decode, len3: %d\r\n", len3);
return 0;
}
PPP数据成帧转义,JAVA语言实现
private static final char PPP_FRAME_FLAG = 0x7E;
private static final char PPP_FRAME_ESC = 0x7D;
private static final char PPP_FRAME_ENC = 0x20;
// PPP数据帧每一帧都以标识字符0x7E开始和结束;
// 由于标识字符的值是0x7E,因此当该字符出现在信息字段中时,PPP需要对它进行转义。
// 当PPP使用异步传输时,它把转义字符定义为:0x7D,并使用字节填充RFC-1662标准。
// 字节填充RFC-1662标准规定如下:
// 1. 把信息字段中出现的每一个0x7E字符转变成字节序列(0x7D,0x5E)
// 2. 若信息字段中出现一个0x7D的字节(即出现了与转义字符相同的比特组合),
// 则把0x7D转义成两个字节序列(0x7D,0x5D)
// 3. 若信息字段中出现ASCII码的控制字符(即数值小于0x20的字符),
// 则在该字符前面加入一个0x7D字节,同时将该字符的编码加以改变
public static char[] ppp_encode(char[] in) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < in.length; i++) {
if (in[i] == PPP_FRAME_FLAG || in[i] == PPP_FRAME_ESC || in[i] < 0x20) {
sb.append((char) PPP_FRAME_ESC);
sb.append((char) (in[i] ^ PPP_FRAME_ENC));
} else {
sb.append(in[i]);
}
}
char[] out = sb.toString().toCharArray();
return out;
}
// PPP数据帧每一帧都以标识字符0x7E开始和结束;
// 由于标识字符的值是0x7E,因此当该字符出现在信息字段中时,PPP需要对它进行转义。
// 当PPP使用异步传输时,它把转义字符定义为:0x7D,并使用字节填充RFC-1662标准。
// 字节填充RFC-1662标准规定如下:
// 1. 把信息字段中出现的每一个0x7E字符转变成字节序列(0x7D,0x5E)
// 2. 若信息字段中出现一个0x7D的字节(即出现了与转义字符相同的比特组合),
// 则把0x7D转义成两个字节序列(0x7D,0x5D)
// 3. 若信息字段中出现ASCII码的控制字符(即数值小于0x20的字符),
// 则在该字符前面加入一个0x7D字节,同时将该字符的编码加以改变
public static char[] ppp_decode(char[] in) {
printHex(in);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < in.length; i++) {
if (in[i] == PPP_FRAME_ESC) {
sb.append((char)(in[i+1] ^ PPP_FRAME_ENC));
i++;
} else {
sb.append(in[i]);
}
}
char[] out = sb.toString().toCharArray();
printHex(out);
return out;
}
串口数据成帧转义,C语言实现
/*
* 0x7e 转义
* 0x7e = 0x7f 01
* 0x7f = 0x7f 02
*/
int mark_7e_encode(unsigned char *in, int in_len, unsigned char *out, int *out_len);
/*
* 0x7e 反转义
* 0x7e = 0x7f 01
* 0x7f = 0x7f 02
*/
int mark_7e_decode(unsigned char *in, int in_len, unsigned char *out, int *out_len);
#define MARK_7E ( 0x7E ) /* 标识字符 */
#define MARK_7F ( 0x7F ) /* 转义字符 */
#define MARK_01 ( 0x01 ) /* 转义字符 */
#define MARK_02 ( 0x02 ) /* 转义字符 */
int mark_7e_encode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
{
unsigned char *pi, *po;
int i, tmp_len;
pi = in;
po = out;
tmp_len = in_len;
for(i = 0; i < in_len; i++)
{
if( *pi == MARK_7E )
{
*po = MARK_7F;
*(++po) = MARK_01;
tmp_len ++;
}
else if(*pi == MARK_7F){
*po = MARK_7F;
*(++po) = MARK_02;
tmp_len ++;
}
else
{
*po = *pi;
}
pi++;
po++;
}
*out_len = tmp_len;
return 0;
}
int mark_7e_decode(unsigned char *in, int in_len, unsigned char *out, int *out_len)
{
unsigned char *pi, *po;
int i, tmp_len;
pi = in;
po = out;
tmp_len = in_len;
for(i = 0; i < in_len; i++)
{
if((*pi == MARK_7F) && (*(pi + 1) == MARK_01))
{
*po = MARK_7E;
po++;
pi +=2;
tmp_len--;
i++;
}else if((*pi == MARK_7F) && (*(pi +1) == MARK_02)){
*po = MARK_7F;
po++;
pi +=2;
tmp_len--;
i++;
}
else
{
*po = *pi;
pi++;
po++;
}
}
*out_len = tmp_len;
return 0;
}
void printf_hex(char *title, unsigned char *hex, int n)
{
int i;
printf("%s", title);
for(i = 0; i < n; i++)
{
if(i % 16 == 0 && i != 0)
printf("\r\n");
printf("%02x ", (unsigned char )hex[i]);
}
printf("\r\n");
}
int main(void)
{
unsigned char p1[256];
unsigned char p2[512];
unsigned char p3[512];
int i, len1, len2, len3;
len1 = sizeof(p1)/sizeof(p1[0]);
for(i = 0; i < len1; i++)
{
p1[i] = i % 256;
}
printf_hex("Before Encode::\r\n", p1, len1);
printf("Before Encode, len1: %d\r\n", len1);
mark_7e_encode(p1, len1, p2, &len2);
printf_hex("After Encode::\r\n", p2, len2);
printf("After Encode, len2: %d\r\n", len2);
mark_7e_decode(p2, len2, p3, &len3);
printf_hex("After Decode::\r\n", p3, len3);
printf("After Decode, len3: %d\r\n", len3);
return 0;
}
串口数据成帧转义,JAVA语言实现
private static final char MARK_7E = 0x7E;
private static final char MARK_7F = 0x7F;
private static final char MARK_01 = 0x01;
private static final char MARK_02 = 0x02;
public static char[] mark_7e_encode(char[] in) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < in.length; i++) {
if (in[i] == MARK_7E) {
sb.append((char) MARK_7F);
sb.append((char) MARK_01);
} else if (in[i] == MARK_7F) {
sb.append((char) MARK_7F);
sb.append((char) MARK_02);
} else {
sb.append(in[i]);
}
}
char[] out = sb.toString().toCharArray();
return out;
}
public static char[] mark_7e_decode(char[] in) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < in.length; i++) {
if ((in[i] == MARK_7F) && (in[i + 1] == MARK_01)) {
sb.append((char) MARK_7E);
i++;
} else if ((in[i] == MARK_7F) && (in[i + 1] == MARK_02)) {
sb.append((char) MARK_7F);
i++;
} else {
sb.append(in[i]);
}
}
char[] out = sb.toString().toCharArray();
return out;
}
网友评论