速求高手,字节压缩的算法问题

yz394777014 2011-03-05 06:34:55
需求环境:
需要把一串字符串通过压缩的办法转化成允许存储空间长度的字节。

例如:字符串(总共17位):“LSJW24H33AS070722”
←-前13位字符(LSJW24H33AS07)由0-9,a-z,A-Z字符组成,后四位(0722)由0-9数字组成。-→

算法代码:

#region str_17to12 17字节源字符串压缩成12个字符串
static void Main(string[] args){
string str17 = "LSJW24H33AS070722";
str17 = "LSJW24HQQAS070722";
Console.WriteLine("" + str17);
char[] tempStr12 = new char[12];
str_17to12(tempStr12, str17.ToCharArray());
//string str12 = Convert.ToString(tempStr12);
Console.WriteLine("$$$$$$$$$$$$$$$$$$$ 17to12");
Console.WriteLine(tempStr12);
Console.WriteLine("$$$$$$$$$$$$$$$$$$$ 17to12");
// Console.WriteLine(str12);

char[] tempStr17 = new char[17];
str_12to17(tempStr17, tempStr12);

//这个数组是通过转换的
//char[] chTagID = tempStr12;
Console.WriteLine("$$$$$$$$$$$$$$$$$$$ 12to17");
Console.WriteLine(tempStr17);
Console.WriteLine("$$$$$$$$$$$$$$$$$$$ 12to17");
// ???
//怎么把转化后的tempStr17字节数组转化成16进制的byte[]?????????????

}
#region str_17to12 17字节源字符串压缩成12个字符串
/*====================================================================*/
/* */
/* FUNCTION: str_17to12 */
/* */
/* sz12 : 12字节目标缓存 */
/* sz17 : 17字节源字符串 */
/*====================================================================*/
static int str_17to12(char[] sz12, char[] sz17)
{
char[] src = new char[18];
char[] dst = new char[13];
int i;
int j;
int rc = 0;
if (null == sz12 || null == sz17)
{
return -1;
}
if (null == sz12 || null == sz17)
{
return -1;
}
Array.Copy(sz17, 0, src, 0, 17);
for (i = 0; i < 17; i++)
{
src[i] = Convert.ToChar(src[i] - 0x30);
}

// 4bit 存1个byte(代表一个字符)
sz12[11] = Convert.ToChar((src[16] & 0x0f) | (src[15] & 0x0f) << 4);
sz12[10] = Convert.ToChar((src[14] & 0x0f) | (src[13] & 0x0f) << 4);

sz12[9] = Convert.ToChar((src[11] << 6) | (src[12] & 0x3f)); // 11(2) + 12(6)
sz12[8] = Convert.ToChar((src[10] << 4) | (src[11] >> 2)); // 10(4) + 11(4)
sz12[7] = Convert.ToChar((src[9] << 2) | (src[10] >> 4)); // 9(6) + 10(2)
sz12[6] = Convert.ToChar((src[7] << 6) | (src[8] & 0x3f)); // 7(2) + 8(6)
sz12[5] = Convert.ToChar((src[6] << 4) | (src[7] >> 2)); // 6(4) + 7(4)
sz12[4] = Convert.ToChar((src[5] << 2) | (src[6] >> 4)); // 5(6) + 6(2)
sz12[3] = Convert.ToChar((src[3] << 6) | (src[4] & 0x3f)); // 3(2) + 4(6)
sz12[2] = Convert.ToChar((src[2] << 4) | (src[3] >> 2)); // 2(4) + 3(4)
sz12[1] = Convert.ToChar((src[1] << 2) | (src[2] >> 4)); // 1(6) + 2(2)
sz12[0] = Convert.ToChar(src[0] & 0x3f); // 6bit存储一个字符
return rc;
}
#endregion

#region str_12to17 12字节源字符串还原成17个字符串
/*====================================================================*/
/* */
/* FUNCTION: str_12to17 */
/* */
/* sz17 : 12字节目标字符串 */
/* sz12 : 12节源缓存 */
/*====================================================================*/
static int str_12to17(char[] sz17, char[] sz12)
{
int i, j;
int rc = 0;
char a, b, c;
// 1个4 bit 存1个byte(代表一个字符)
// 1个byte=8bit 前4bit为高4位,后4bit为低4位 (一般高4位有用)
sz17[16] = Convert.ToChar(sz12[11] & 0x0f);
sz17[15] = Convert.ToChar((sz12[11] & 0xf0) >> 4);
sz17[14] = Convert.ToChar(sz12[10] & 0x0f);
sz17[13] = Convert.ToChar((sz12[10] & 0xf0) >> 4);

sz17[12] = Convert.ToChar(sz12[9] & 0x3f);
sz17[11] = Convert.ToChar(((sz12[9] & 0xc0) >> 6) | ((sz12[8] & 0x0f) << 2));
sz17[10] = Convert.ToChar(((sz12[8] & 0xf0) >> 4) | ((sz12[7] & 0x03) << 4));
sz17[9] = Convert.ToChar((sz12[7] & 0xfc) >> 2);
sz17[8] = Convert.ToChar(sz12[6] & 0x3f);
sz17[7] = Convert.ToChar(((sz12[6] & 0xc0) >> 6) | ((sz12[5] & 0x0f) << 2));
sz17[6] = Convert.ToChar(((sz12[5] & 0xf0) >> 4) | ((sz12[4] & 0x03) << 4));
sz17[5] = Convert.ToChar((sz12[4] & 0xfc) >> 2);
sz17[4] = Convert.ToChar(sz12[3] & 0x3f);
sz17[3] = Convert.ToChar(((sz12[3] & 0xc0) >> 6) | ((sz12[2] & 0x0f) << 2));
sz17[2] = Convert.ToChar(((sz12[2] & 0xf0) >> 4) | ((sz12[1] & 0x03) << 4));
sz17[1] = Convert.ToChar((sz12[1] & 0xfc) >> 2);
sz17[0] = Convert.ToChar(sz12[0] & 0x3f); // 6bit 存 1 byte(代表一个字符)

for (i = 0; i < 17; i++)
{
sz17[i] = Convert.ToChar(sz17[i] + 0x30);
}
return rc;
}
#endregion6bit 存 1 byte(代表一个字符)

for (i = 0; i < 17; i++)
{
sz17[i] = Convert.ToChar(sz17[i] + 0x30);
}
return rc;
}
#endregion

提出问题:
怎么把转化后的tempStr17字节数组转化成16进制的byte[]?????????????

解决方案建议:
这个如果使用C#系统的自带的API来转化时,我认为可能有问题?
例如:byte[] wrData = Encoding.Unicode.GetBytes(tempStr12);// 这个转化后的byte[]不是16进制的byte数组
还是需要到转化的代码中去考虑?到目前还不知道怎么转化?希望有高手帮忙解决这个问题?
...全文
347 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Code従業員 2011-03-08
  • 打赏
  • 举报
回复
原来是硬件设置,char[17]转换成char[12],在把char[12]的存放的数据转换成byte[24],这样是很麻烦的,楼上说取6位可以勉强实现,但是到拆装字的算法让人头大,而且运算效率低下。

C#默认使用UNICODE编码,为了字符大小恒等,所有字符都占到了一个字单元,如果编码是你上文要求的范围内的话,我建议使用ASCII或者ANSI编码,这些英文字符都占1字节的编码。省去转换的麻烦,而且24字节放17个字符绰绰有余。

当然,在C#环境下我没试过,是不是硬性占那么大没有试过。没环境没法测,你看看吧。
bloodish 2011-03-06
  • 打赏
  • 举报
回复
纠错
记住C#中Char是双字节(0~65535),Byte(0~255)
bloodish 2011-03-06
  • 打赏
  • 举报
回复
什么是16进制的Byte[]?
无论进制是二进制,八进制,十进制,十六进制,数字在内存中的表示是一样的(大端或小端).
记住C#中Char是双字节(0~65536),Byte(0~255)
var charArray = new char[12];
var byteArray = new byte[24];
for(int i=0,j=0;i<charArray.Length;i++)
{
byteArray[j++] = (byte)((ushort)charArray[i] & 0x00FF);
byteArray[j++] = (byte)((ushort)(charArray[i] >> 8) & 0x00FF);
}
验证码识别 2011-03-06
  • 打赏
  • 举报
回复
自己对字符编码

一共 26+26 个字符 6位(一个字节8位)表示一个, 13个字符用 13*6/8 = 10字节
10个数字 4位表示一个, 4个字符用 4*4/8 = 2字节

刚好12字节能表示
lizhibin11 2011-03-06
  • 打赏
  • 举报
回复

static unsafe void Main(string[] args)
{
char[] x = new char[12];
byte* y;
fixed(char* p = x)
{
y = (byte*)p;
//y[0]......
//y[1]......
}
}
yz394777014 2011-03-06
  • 打赏
  • 举报
回复
icbdow 您好:
你说的是,小霸王游戏机都有8位,确实如此,其实我的应用时这样的,现在有一台RFID射频扫描器,这是一个射频扫描技术,主要由一个RFID扫描器要针对一个RFID芯片(就一块独立小芯片)进行扫描获取数据或存储数据到这个小芯片上,现在这个小芯片的存储空间有三个区可以访问:
1. EPC (只能存储24位的byte[]数据)
2. TID(存储TID数据,只读不可写)
3. USER(存储数据)
现在只有EPC的一片空间可以写数据,但是存储的空间过小,需要对char[17]转换成char[12],在把char[12]的存放的数据转换成byte[24]才能存储到这个小芯片上。
方法的API:

virtual void WriteTagID(
TagType tagType,
byte[] tagID
)

现在这个两个算法经测试压缩通过,就是在压缩后的char[12]怎么转化成16进制的byte[24]?





Code従業員 2011-03-05
  • 打赏
  • 举报
回复
看了半天,原来这样压缩的啊,只取4位。

我提些问题,如果按照你所谓的4位取法,那么你的前4位最多能够存储16个不同的数,但是看到你的题目A~Z,a~z,0~9,这样搞好像放不完吧?

即使放的下,光大写的A键码就65了,啥没干就用去了7位,如果你用减法让它放的下,最多也放的16个。第二次一放,前面的数据就损坏了,怎么还原都不可能啊。

听我一句,别压了,小霸王游戏机都有8位啊。
wuyq11 2011-03-05
  • 打赏
  • 举报
回复

byte[] data = Encoding.Default.GetBytes("");
StringBuilder sb= new StringBuilder();
foreach (byte b in data)
{
sb.Append(b.ToString("X02") + " ");
}
Console.WriteLine(sb.ToString().TrimEnd());

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧