读书人

怎么分割长unsigned char类型字符串

发布时间: 2012-03-20 14:01:11 作者: rapoo

如何分割长unsigned char类型字符串,全部按5个bit位存在一个char类型的数组中?
现在有一个字符串
unsigned char byteSrc[40];
共 40*8 (bits)
想从低位开始,把这40*8个bits从低到高依次取出,
每次5个bits,
并把每个取出的bits依次放在
unsigned char byteDes[64];
中,
按字节存,
大家有没有好的办法?


[解决办法]
好像没有什么好办法.lz为什么要按5个bit存呢?
[解决办法]
①从byteSrc[0]取5个bit
②从byteSrc[0]取剩下的3个,从byteSrc[1]取2个
。。。。。。
[解决办法]
我推荐lz用位域阿


[解决办法]
用原始方法,一个一个填
[解决办法]
typedef struct tag_5bits
{
unsinged char ch:5;
}_5bits;


unsigned char byteSrc[40];
_5bits bys[40];

memcpy(bys, byteSrc, 40);


就是这样了~



[解决办法]
lz的方法我觉得还是很不错的,效率也不错。
可以考虑把
outDscp[count++] = ((b3 & 0xF0)> > 4) + ((b4 & 0x01) < <4)
中的加法换成位或稍微提高一点点效率。

如果觉得效率还不够,那就上汇编吧
[解决办法]
#include <iostream>

int main()
{
using namespace std;
double tmp[5] = {234.532,535.676,-235e34,45.3e-32,-343.4e-45}; //40 bytes = 320 bits
unsigned char * byteSrc = reinterpret_cast <unsigned char * > (tmp);
unsigned char byteDst[64];
cout < <sizeof(tmp) < <endl;
//转化,byteSrc[0]低5位(0-4)存在byteDst[0],byteSrc[39]高5位(3-7)存在byteDst[63],所有字节序无变化
const unsigned char MASK = 0x1F;
for(int i = 0,j = 0,bit = 0;i < 40;++j){
byteDst[j] = (byteSrc[i] > > bit) & MASK;//(byteSrc[i] & (MASK < < bit)) > > bit;
if((bit += 5) > 7)
byteDst[j] += (byteSrc[++i] < < (5 - (bit -= 8))) & MASK;
}
//测试结果
const char * SRC_BIN[16] = { "0000 ", "0001 ", "0010 ", "0011 ", "0100 ", "0101 ", "0110 ", "0111 ",
"1000 ", "1001 ", "1010 ", "1011 ", "1100 ", "1101 ", "1110 ", "1111 ",};
cout < < "Source:\n ";
for(int i = 39;i > =0;--i){
cout < <SRC_BIN[byteSrc[i] > > 4] < < " ";
cout < <SRC_BIN[byteSrc[i] & 0xF] < < " ";
}
cout < <endl;
const char * DST_BIN[2] = { "xxx0 ", "xxx1 "};
cout < < "Dest:\n ";
for(int i = 63;i > =0;--i){
cout < <DST_BIN[byteDst[i] > > 4] < < " ";
cout < <SRC_BIN[byteDst[i] & 0xF] < < " ";
}
cout < <endl;
}

[解决办法]
typedef struct {
unsigned long a0:5;
unsigned long a1:5;
unsigned long a2:5;
unsigned long a3:5;
unsigned long a4:5;
unsigned long a5:5;
unsigned long a6:2;
}BIT;


main()
{
unsigned char byteSrc[40];
unsigned long *p,tmp;
for(int i = 0;i < 40;i++)
{
byteSrc[i] = i % 2;
}
BIT *bitmap;


p = (unsigned long *)byteSrc;

tmp = *p;
for(i = 0;i < (40 / 4) ; i++)
{
tmp = *p;

if( i != 0)
{
tmp = ((*p) > > 2) | (((bitmap-> a5) < <30) & 0xcFFFFFFF);
}
bitmap = (BIT * )(&tmp);//这个前面5位是可以取出来的!
p++;
}
}
[解决办法]
好像和base64编码一个道理,参考一下base64编码实现

/* Redefinition protection */
#ifndef __BASE64_H__
#define __BASE64_H__

/*

The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
When encoding a bit stream via the base64 encoding, the bit stream
must be presumed to be ordered with the most-significant-bit first.
That is, the first bit in the stream will be the high-order bit in
the first 8bit byte, and the eighth bit will be the low-order bit in
the first 8bit byte, and so on.

The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y

Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a body. When fewer than 24 input bits
are available in an input group, zero bits are added (on the right)
to form an integral number of 6-bit groups. Padding at the end of
the data is performed using the "= " character. Since all base64
input is an integral number of octets, only the following cases can
arise: (1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded output will be
an integral multiple of 4 characters with no "= " padding, (2) the
final quantum of encoding input is exactly 8 bits; here, the final
unit of encoded output will be two characters followed by two "= "
padding characters, or (3) the final quantum of encoding input is
exactly 16 bits; here, the final unit of encoded output will be three
characters followed by one "= " padding character.

source: rfc2045,rfc2046

*/

/* use pure C */
#ifdef __cplusplus
extern "C "
{
#endif
/* Base64 Alphabet */
static const char szBase64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ ";

/**
* Base64 Encode
* note: 编码后的长度一般比原文多占1/3的存储空间,请保证base64code有足够的空间
*/
TOOLDLLIMP int Base64Encode(char* base64code, const unsigned char *src, int len);



/**
* Base64 Encode
* note: 编码后的长度一般比原文多占1/3的存储空间,请保证base64code有足够的空间
*/
TOOLDLLIMP int _Base64Encode(char** base64code, const unsigned char *src);

/**
* Base64 Decode
* note:解码后的长度一般比原文少用占1/4的存储空间,请保证buf有足够的空间
*/
TOOLDLLIMP int Base64Decode(unsigned char* str, const char * base64code, int len);

/**
* Base64 Decode
* note:解码后的长度一般比原文少用占1/4的存储空间,请保证buf有足够的空间
*/
int _Base64Decode(unsigned char** str, const char* base64code);

/**
* Get Base64 char
*/
TOOLDLLIMP char GetBase64Value(char ch)
{
if ((ch > = 'A ') && (ch <= 'Z '))
return ch - 'A ';
if ((ch > = 'a ') && (ch <= 'z '))
return ch - 'a ' + 26;
if ((ch > = '0 ') && (ch <= '9 '))
return ch - '0 ' + 52;
switch (ch) {
case '+ ':
return 62;
case '/ ':
return 63;
case '= ': /* base64 padding */
return 0;
default:
return 0;
}
}

/**
* Base64 Encode
* @param: base64code
* @param: src
* @param: len
* @return: succeed return number base encode, else return -1
*/
TOOLDLLIMP int Base64Encode(char* base64code, const unsigned char *src, int len)
{
/* declare variables */
int buflen=0;
const unsigned char *str = src;
char *p = base64code;
/* recovery programming */
if(len == 0)
len = (int)strlen((const char*)str);

/* */
while(len > 0)
{
/* first code */
*base64code++ = szBase64Table[((str[0]&0xFF) > > 2) & 0X3F];
/* two , second, four*/
if(len > 2)
{
*base64code++ = szBase64Table[((str[0]&0xFF) < < 4 |(str[1]&0xFF) > > 4)&0x3F];
*base64code++ = szBase64Table[((str[1]&0xFF) < < 2 |(str[2]&0xFF) > > 6)&0x3F];
*base64code++ = szBase64Table[((str[2]&0xFF))& 0x3F];
}
else
{
if(len == 1)
{
*base64code++ = szBase64Table[((str[0]&0xFF) < < 4) &0x3F];
*base64code++ = '= ';
*base64code++ = '= ';
}
else if(len == 2)
{
*base64code++ = szBase64Table[((str[0]&0xFF) < < 4 |(str[1]&0xFF) > > 4)&0x3F];
*base64code++ = szBase64Table[((str[1]&0xFF) < < 2 |(str[2]&0xFF) > > 6)&0x3F];
*base64code++ = '= ';
}
}
len -= 3;
str += 3;
buflen +=4;
}
/* end string */
*base64code = '\0 ';

/* return value */
return buflen;
}

/**
* Base64 Encode
* @param: base64code
* @param: src
* @return: succeed return number base encode, else return -1
*/
int _Base64Encode(char** base64code, const unsigned char *src)
{
/* declare variables */
int len = 0;

/* source string length */
len = (int)strlen((const char*)src);

*base64code = (char*)malloc((len/3+1)*4+1);
if(*base64code == NULL)
return -1;

/* return value */
return Base64Encode(*base64code,src,len);

}

/**
* Base64 Decode
* @param: str
* @param: base64code,
* @param: len
* @return: succeed return number base encode, else return -1
*/
TOOLDLLIMP int Base64Decode(unsigned char* str, const char * base64code, int len)
{
/* declare variables */
unsigned char chunk[4];
int str_len=0;


int temp = 0;
/* recovery programming */
if(len == 0)
len = (int)strlen(base64code);
if(len%4)
return -1;

temp = len -4;
while( temp > 0 )
{
chunk[0] = GetBase64Value(base64code[0]);
chunk[1] = GetBase64Value(base64code[1]);
chunk[2] = GetBase64Value(base64code[2]);
chunk[3] = GetBase64Value(base64code[3]);

*str++ = (chunk[0] < < 2) | (chunk[1] > > 4);
*str++ = (chunk[1] < < 4) | (chunk[2] > > 2);
*str++ = (chunk[2] < < 6) | (chunk[3]);

base64code += 4;
temp -= 4;
str_len += 3;
}
/* deal data "= " */
chunk[0] = GetBase64Value(base64code[0]);
chunk[1] = GetBase64Value(base64code[1]);
chunk[2] = GetBase64Value(base64code[2]);
chunk[3] = GetBase64Value(base64code[3]);

/* first */
*str++ = (chunk[0] < < 2) | (chunk[1] > > 4);
++str_len;

if(chunk[1] != 0 && chunk[2] != 0)
{
*str++ = (chunk[1] < < 4) | (chunk[2] > > 2);
++str_len;
}

if(chunk[2] != 0 && chunk[3] != 0)
{
*str++ = (chunk[2] < < 6) | (chunk[3]);
++str_len;
}

*str = '\0 ';
/* return value */
return str_len;
}

/**
* Base64 Decode
* @param: str
* @param: base64code,
* @param: len
* @return: succeed return number base encode, else return -1
*/
int _Base64Decode(unsigned char** str, const char* base64code)
{
/* declare variables */
int len = 0;
len = (int)strlen(base64code);

*str = (unsigned char*) malloc( (len/4)*3+1);

/* return value */
return Base64Decode(*str,base64code,len);
}


/* use pure C */
#ifdef __cplusplus
}
#endif

/* Redefinition protection */
#endif


读书人网 >C语言

热点推荐