COBSforN 编码算法(C + java)

本文详细介绍了COBS(Consistent Overhead Byte Stuffing)算法的工作原理,包括其在C语言和Java中的实现。通过恒定开销的字节填充,COBS确保了编码后的数据帧清晰分割,适用于需要处理特殊字符序列的场景。

COBS(Consistent Overhead Byte Stuffing,恒定开销的字节填充)是一种固定开销的字节填充算法。字节填充用于处理那些包含了特殊或保留字符的字符序列编码,通过一定的算法在原有的字符序列长度+1 生成编码后的字符序列,新的序列将不会包含之前序列中出现的特殊或者保留的字符。

在ForN版本中,编码后的有效字节均为非0数据 (1~255)。以为数据0为结束。编码中0xFF为超出255而做中继. 该种编码的特点是整个数据帧有且只有一个数据0,而且它为结束数据, 这样对于分包处理有明显的分割.

参考::>

https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing

=====C语言版本=========

#include <stdint.h>
#include <assert.h>

/** COBS encode data to buffer
	@param data Pointer to input data to encode
	@param length Number of bytes to encode
	@param buffer Pointer to encoded output buffer
	@return Encoded buffer length in bytes
	@note Does not output delimiter byte
*/
size_t cobsEncode(const void *data, size_t length, uint8_t *buffer)
{
	assert(data && buffer);

	uint8_t *encode = buffer; // Encoded byte pointer
	uint8_t *codep = encode++; // Output code pointer
	uint8_t code = 1; // Code value

	for (const uint8_t *byte = (const uint8_t *)data; length--; ++byte)
	{
		if (*byte) // Byte not zero, write it
			*encode++ = *byte, ++code;

		if (!*byte || code == 0xff) // Input is zero or block completed, restart
		{
			*codep = code, code = 1, codep = encode;
			if (!*byte || length)
				++encode;
		}
	}
	*codep = code; // Write final code value

	return encode - buffer;
}

/** COBS decode data from buffer
	@param buffer Pointer to encoded input bytes
	@param length Number of bytes to decode
	@param data Pointer to decoded output data
	@return Number of bytes successfully decoded
	@note Stops decoding if delimiter byte is found
*/
size_t cobsDecode(const uint8_t *buffer, size_t length, void *data)
{
	assert(buffer && data);

	const uint8_t *byte = buffer; // Encoded input byte pointer
	uint8_t *decode = (uint8_t *)data; // Decoded output byte pointer

	for (uint8_t code = 0xff, block = 0; byte < buffer + length; --block)
	{
		if (block) // Decode block byte
			*decode++ = *byte++;
		else
		{
			if (code != 0xff) // Encoded zero, write it
				*decode++ = 0;
			block = code = *byte++; // Next block length
			if (code == 0x00) // Delimiter code found
				break;
		}
	}

	return decode - (uint8_t *)data;
}

==============Java版本====================

   public static  int[] COBS_Encoded(int[] data_in)
    {

        ArrayList encodeList = new ArrayList();  
        encodeList.add(0);
        int i,len = data_in.length;
        int zeroPos = 0;
        int zeroAdds= 1;
        int temp = 0;
        
        for(i=0;i<len;i++)
        {
            encodeList.add( data_in[i] );
        }
        encodeList.add(0);
 

        for(i=1;i<encodeList.size();i++)
        {
          
            temp = (int)encodeList.get(i); 
            if( temp == 0 )
            {
                encodeList.set(zeroPos,zeroAdds);
                zeroPos += zeroAdds;
                zeroAdds = 0;
            }
              zeroAdds++;
            if( zeroAdds>=0xFF)
            {
                  encodeList.set(zeroPos,0xFF);
                  encodeList.add(i+1,0); 
                  i++; 
                  zeroPos += zeroAdds;
                  zeroAdds = 1; 
            }
            
        }
        
        len = encodeList.size();
        int[] retDst = new int[len];
        for(i=0;i<len;i++)
        {
            retDst[i] = (int)encodeList.get(i);
        }        
        
       return retDst;
}
    
public static int[] COBS_Decode(int[] data)    
{
    int i,len = data.length;
    int temp = 0;  
    
	ArrayList encodeList = new ArrayList();
	
	for(i=0;i<len;i++)
	{
	    encodeList.add(i,data[i]);
	}

	int zValue = data[0];
    int zIndex = 0;
	for(i=0;i<encodeList.size();i++)
	{
	    temp = (int)encodeList.get(i);
    	if(zIndex==zValue)
    	{
    	    if(zValue == 0xFF ) 
    	    {
    	        temp = (int)encodeList.get(i);//key position
    	        encodeList.remove(i);
    	        
    	    }else{
    	        encodeList.set(i,0);
    	      
    	    }
    	        
    	        zIndex = 0;
    	        zValue = temp;
    	}
    	   
	     zIndex++;

	}

	
	encodeList.remove(0);
	len = encodeList.size();
	if( (int)encodeList.get(len-1) == 0x00)
	{
	    encodeList.remove(len-1);
	    len--;
	}
	
	int[] retDst = new int[len]; 
	for(i=0;i<len;i++)
	{
	    retDst[i] = (int)encodeList.get(i);
	}
	return retDst;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值