简单数学问题,求解[多多散分]

Lorenes 2003-08-23 01:25:14
标题:数据格式转换

共两种数据格式,

第一种(以下简称 格式A)
长度: 32字节
最小:00000000000000000000000000000000
最大:ffffffffffffffffffffffffffffffff
组成: 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
例子:586284651a72b782c72851984265d78e
容量: 15种可能性 x 32位

可见是典型16进制表示的数

第二种(以下简称 格式B)
长度: 24字节
最小:aaaaaaaaaaaaaaaaaaaaaaaa
最大:555555555555555555555555
组成:a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5
例子:zj6d8r651a72b7u2c728n198
容量: 32种可能性 x 24位


当然,看起来 格式B 比 格式A 容量大些.

如何,将任意一个 格式A 的数据转换为 格式B 的数据格式,
能并还原回 格式A ?
...全文
35 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lorenes 2003-09-04
  • 打赏
  • 举报
回复
木头象大哥,给你分!!!

我后来研究了一下,得出如下结论:
32位16可能转换为 24位32可能这道题,无解!答案是不可能.

对于你的算法,我的C# Function是.


public static string NXENC(ulong num,uint newbit,string HexLst){//to AnyBit
//if(HexLst.Length<newbit){HexLst=@"0123456789";}

//bool neg=(num<0);
string newnum=@"";

//if(newbit==10||num==0){return(@"0");}

//num=System.Math.Abs(num);
while(num!=0){
//newnum=HexLst.charAt(num%newbit)+newnum;
//num=Math.floor(num/newbit);
newnum=(HexLst.Substring((int)(num%newbit),1)).ToString()+newnum;
num=(ulong)(num/newbit);}

//if(neg){newnum=@"-"+newnum;}

return((newnum).ToString());}


public static ulong NXDEC(string num,uint oldbit,string HexLst){//To 10
//64,62,36
//if(HexLst.Length<oldbit){HexLst=@"0123456789";}
//if(oldbit==10||num==@"0"){return(0L);}

//bool neg=num.StartsWith(@"-");
//if(neg){num=num.Substring(1);}

ulong newnum=0;
for(int index=1;index<=num.Length;index++){
newnum = (newnum*oldbit) +(uint)HexLst.IndexOf(( num.Substring(index-1,1) ).ToString());//Idx
}

//if(neg){newnum=-newnum;}
return(newnum);}
gujianxin 2003-09-04
  • 打赏
  • 举报
回复
怎么会是不可能的呢?

只要不超过范围就可以了

你的代码很不错,不过别人怕是看不懂...

呵呵
standy 2003-08-29
  • 打赏
  • 举报
回复
thanks
gujianxin 2003-08-29
  • 打赏
  • 举报
回复
谢我?

you are welcome
firejie 2003-08-26
  • 打赏
  • 举报
回复
接分
gujianxin 2003-08-26
  • 打赏
  • 举报
回复
将A格式看做16进制,B格式看做32进制,

通过Byte数组来做中间量做转换,如下

16进制: 1111 1011 1100 1110 0001 0000 0010 1010 1011 1101
byte数组: 11111011 11001110 00010000 00101010 10111101
32进制 : 11111 01111 00111 00001 00000 01010 10101 11101


A格式的每一个字符占四位,将2个合成1个byte,比较容易

A格式的每一个字符占五位,转成byte数组相对麻烦一些,费了我点时间 :)

gujianxin 2003-08-26
  • 打赏
  • 举报
回复
using System;

namespace T16to32
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class TestT16
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
string sou = "d38a9bF87CE";
string s32 = Magic.Char16To32(sou);
string s16 = Magic.Char32To16(s32);

if(sou.ToUpper() == s16)
Console.WriteLine("Test Result :\t sou = '"+sou+"',s32 = '"+s32+"', s16 = '"+s16+"', the test result is very successful!");

Console.Read();
}
}

public class Magic
{
/// <summary>
/// 将16进制转成32进制
/// </summary>
/// <param name="s16"></param>
/// <returns></returns>
public static string Char16To32(string s16)
{
byte[] temp = Char16ToByte(s16);
return ByteTo32(temp);
}

/// <summary>
/// 将32进制转成16进制
/// </summary>
/// <param name="s32"></param>
/// <returns></returns>
public static string Char32To16(string s32)
{
byte[] temp = Char32ToByte(s32);
return ByteTo16(temp);
}

/// <summary>
/// 将byte数组转成32进制字符串
/// </summary>
/// <param name="medi"></param>
/// <returns></returns>
protected static string ByteTo32( byte[] medi )
{
short left = 5; //下一个byte中包含当前数字的位数(1->5)
int cur = 0; //当前数字;
string sRe = "";
for(int i =medi.Length -1 ; i >=0 ; i --)
{
byte temp = medi[i];
int con = ((temp) << (5 - left) ) + cur;
sRe = Get32Char((byte)(con & 0x1f )) + sRe;
cur = (temp ) >> (left);
left -= 3;

// 又完成一个字符
if(left < 1)
{
con = cur << (-left);
con = con >> (-left);
sRe = Get32Char((byte)(con & 0x1f )) + sRe;
cur = cur >> 5;

left += 5;
}
}

return sRe;
}


/// <summary>
/// 10 to 32
/// </summary>
/// <param name="cur"></param>
/// <returns></returns>
private static char Get32Char( byte cur)
{
if((cur < 0 ) || (cur > 32))
throw new Exception("无效的数字");
//将一个字符加入
if(cur < 26)
return (char)('A' + cur);
else
return (char)('0' + (cur - 26));

}

/// <summary>
/// 提取32进制串的一位
/// </summary>
/// <param name="ch"></param>
/// <returns></returns>
private static byte Get32Int(char ch)
{
if((ch >= 'A')&& ( ch <= 'Z') )
return (byte)(ch - 'A');
else if ((ch >= '0') && ( ch <= '5' ) )
return (byte)(26 + (ch - '0'));
else
throw new Exception("无效的字符");
}


/// <summary>
/// 将32进制字符串转成byte数组
/// </summary>
/// <param name="sou"></param>
/// <returns></returns>
protected static byte[] Char32ToByte(string sou)
{
char[] ch = sou.ToUpper().ToCharArray();
int t = (ch.Length * 5) % 8;
byte[] re = new byte[ch.Length * 5 /8 + ((t ==0)?0: 1)];

int left = 5; //下一个byte中包含当前数字的位数(1->5)
int cur = 0; //当前数字;
int exists = 0;
int pos = ch.Length - 1;

for(int i = re.Length -1 ; i >= 0; i --)
{
int temp = (Get32Int(ch[pos]) << exists) + cur;
exists += left;


if(exists > 7)
{
if(exists > 8)

throw new Exception("error");

re[i] = (byte)temp;
cur = (Get32Int(ch[pos]) >> (left));
pos --;
}
else
{
if(pos < 0)
throw new Exception("error");
/*
*
11111 01111 00111 00001 00000 01010 10101 11101
0 5 0
5 3 0x11101
3 8 0x10
2 5 0x0101010
*/
left = ((8 - exists) > 5)?5:(8 - exists);
if(pos != 0)
{
temp = (Get32Int(ch[pos-1]) << exists) + temp;
cur = (Get32Int(ch[pos-1]) >> (left));
}
re[i] = (byte)temp;

pos -= 2;
}

exists = 5 - left;
left = ((8 - exists) > 5)?5:(8 - exists);

}


return re;
}

/// <summary>
/// 将byte数组转成十六进制字符串
/// </summary>
/// <param name="medi"></param>
/// <returns></returns>
protected static string ByteTo16 (byte[] medi)
{
string sRe = medi[0].ToString("X");
for(int i = 1 ; i< medi.Length; i++)
{
sRe += medi[i].ToString("X2");
}
return sRe;
}

/// <summary>
/// 将十六进制字符串转为byte数组
/// </summary>
/// <param name="sou"></param>
/// <returns></returns>
protected static byte[] Char16ToByte(string sou)
{
char[] ch = sou.ToUpper().ToCharArray();

int len = ch.Length;
if((len % 2) == 1 )
len += 1;
byte[] re = new byte[len/2];
int chlen = ch.Length;
int relen = re.Length;

for(int i = 0 ; i < (relen -1 ) ; i ++)
{
re[relen -1 - i] = (byte)(GetHex(ch[chlen - 2 - 2*i ]) * 16 +GetHex(ch[chlen - 1 - 2*i]));
}
if(len == chlen)
re[0] = (byte)(GetHex(ch[0]) * 16 +GetHex(ch[1]));
else
re[0] = GetHex(ch[0]);

return re;

}

/// <summary>
/// 取得十六进制数
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
private static byte GetHex(char c)
{
byte re;
if( c >= 'A')
re = (byte)(10 + (c - 'A'));
else
re = (byte)(c - '0');

return re;
}


}




}
Lorenes 2003-08-23
  • 打赏
  • 举报
回复
qqq123(qqq123) 大哥,速度也实在太慢点了吧...

麻烦您再帮忙想想...
Lorenes 2003-08-23
  • 打赏
  • 举报
回复
是啊,用10进制的数有点大哦...

用2进制呢? 11010010101010010101010 是不是能稍微好点?

速度可能更慢哦.
qqq123 2003-08-23
  • 打赏
  • 举报
回复
补充:
gujianxin(木头象)的方法需要考虑益处问题。需要建立一个无限长整数类来支持"中间的10进制".
gujianxin 2003-08-23
  • 打赏
  • 举报
回复
将A格式看做16进制,B格式看做24进制,

通过中间的10进制转换

如: B中的bc 等于

1*24 + 2 = 26



26 /16 = 1
26 - 1* 16 = 10

1A

即A格式的1A 对应 B格式的 26

可以通过移位加快运算速度
qqq123 2003-08-23
  • 打赏
  • 举报
回复
using System;
using System.Collections;



namespace CodeChange
{

class Class1
{
static char[] A={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
static char[] B={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
't','u','v','w','x','y','z','0','1','2','3','4','5'};
static char[] Change(char[] a,char[] aBit,char[] bBit)
{
if(aBit.Length<=1 || bBit.Length<=1)
throw new ArgumentException();
if(a.Length==0) return new char[0];
int[] aN=new int[a.Length];
for(int i=0;i<a.Length;i++)
{
aN[i]=(aBit as IList).IndexOf(a[i]);
if(aN[i]==-1)
throw new ArgumentException();
}
ArrayList bN=new ArrayList();
bN.Add(0);
for(;;)
{
bN[0]=(int)bN[0]+aN[0];
for(int j=0;j<bN.Count;j++)
{
if(((int)bN[j])>=bBit.Length)
{
if(j+1>=bN.Count)
bN.Add(0);
bN[j+1]=((int)bN[j+1])+((int)bN[j])/bBit.Length;
bN[j]=((int)bN[j])%bBit.Length;
}
else
{
break;
}
}
aN[0]=0;
int k=0;
for(k=1;k<aN.Length;k++)
{
if(aN[k]!=0)
{
aN[k]--;
for(int n=k-1;n>0;n--)
{
aN[n]=aBit.Length-1;
}
aN[0]=aBit.Length;
break;
}
}
if(k>=aN.Length)
break;
}
char[] result=new char[bN.Count];
for(int i=0;i<bN.Count;i++)
{
result[i]=bBit[(int)bN[i]];
}
return result;
}

[STAThread]
static void Main(string[] args)
{
char[] k=Change(new char[] { '1','2','5','7','2','4','7'},A,B);
for(int i=0;i<k.Length;i++)
Console.WriteLine(k[i].ToString());

char[] k2=Change(k,B,A);
for(int i=0;i<k2.Length;i++)
Console.WriteLine(k2[i].ToString());

Console.ReadLine();
}
}
}
//--------------------------------
该算法速度太慢。
pretender1982 2003-08-23
  • 打赏
  • 举报
回复
我学术不精,但我记得树离散数学历的关于映射函数和数字编码的内容,你是着找一本离散数学的书查一下,我手头没有书
哎,学的知识又还给老师了
xys2000132 2003-08-23
  • 打赏
  • 举报
回复
等答案
Nicholasqpl 2003-08-23
  • 打赏
  • 举报
回复
up
Muzhu 2003-08-23
  • 打赏
  • 举报
回复
学习一下
bluemeteor 2003-08-23
  • 打赏
  • 举报
回复
学习一下
ruanyuping 2003-08-23
  • 打赏
  • 举报
回复
up
Lorenes 2003-08-23
  • 打赏
  • 举报
回复
格式B 的内容,如果觉得

最小:aaaaaaaaaaaaaaaaaaaaaaaa
最大:555555555555555555555555

不适应,也可以是

最小:000000000000000000000000
最大:zzzzzzzzzzzzzzzzzzzzzzzz

都行,只要能用格式B储存并还原就行.

110,533

社区成员

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

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

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