有意思的转换!如何实现16进制与36进制字符串的相互转换?(100分)

  • 主题发起人 主题发起人 luckymanman
  • 开始时间 开始时间
L

luckymanman

Unregistered / Unconfirmed
GUEST, unregistred user!
如:将十六进制字符串:0C0160652414C7DD4ACE9D3970DAE8E6ADF65F3167B10663BCC1998316476A728F553EA4442D40053BCFAEED663061BE6AFEC24E5EACC44A7988FBF2EDDEFB25FAB转为36进制表示的字符串。(36进制就是用这36个数字字母表示的进制数:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ)。
有哪位富翁做过这类转换?这样做的好处是可以压缩字符串长度。
如实现这样的函数
function Str16ToStr36(str16:string):string;
function Str36ToStr16(str36:string):string;
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=13396
 
to xianguo:你提供的我已经看过了,参数不是长字符串,而是整数,即使是int64的范围也没有这么大。
 
你找一下base64编码的实现。
 
两位两位的取 0C 01 60 65 ...
 
base64编码比较简单,但36进制麻烦点,哪位富翁做过的来讨论一下。
 
应该比较简单的吧

16进制表示的值用你36进制的表示就可以了
 
char数组=('0',123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ)//从上边拷贝的,呵呵
16数->36进制数 例如 20(32)->12
根据以上的组成36进制串
然后以36进制串中的每一位作为数组下标替换为数组中的字符
我想到的是这个笨方法(我才入门半年嘛,自己都原谅自己拉,呵呵),请楼下的高手
不吝指教
 
想了想,自己测试了一下
//16进制串转换成36进制串
//16进制数为2个字节长度
procedure TForm1.Button1Click(Sender: TObject);
var
s,t:string;
B,c:integer;
i,flag:integer;
Temp:integer;
Template:string;
Temps,tail:string;
begin
Temps:='';
Template:='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
flag:=1;
//16进制到36进制的转换
s:='0C0160652414C7DD4ACE9D3970DAE8E6ADF65F3167B10663BCC1998316476A7'+
'28F553EA4442D40053BCFAEED663061BE6AFEC24E5EACC44A7988FBF2EDDEFB25FAB';
for i:= 1 to length(s)div 2 do
begin
t:=copy(s,flag,2);
Temp:=strtoint('$'+t);
b:=Temp div 36;
c:=Temp mod 36;
Temps:=Temps+Template[b+1]+Template[c+1];
flag:=flag+2;
end;
showmessage(Temps);
end;
丑也不怕.嘿嘿
 
进制必然是对应整数的,不然就不叫进制,而仅仅是编码而已.因此36进制是没有什么意义的,因为它不能直接对应比特流(那么就必须对应整数)(其实也不是不可转换使用36个字符表示,但是算法太过于复杂,效率及其低下,而且就我想到的算法,是不能够随机检索的,只能从头全部处理).
我想你应该做的是把一串由0-F字符组成的字符串转换成一个字节流,然后把它们看成比特流. 16进制是每4比特用一个字符,那么32进制就可以每5比特用一个字符,(36进制就没必要了,否则你干脆直接用64进制就好了),

16进制->32进制转换仅仅能够节省20%左右的字符,然而却会带来处理上的麻烦和效率低下,你需要确认真的有此需要.

function Hex_5Char_To_32_4Char_20BIT(c0, c1, c2, c3, c4 as Char):string;
var
iVal as Integer;
begin
SetLength(Result, 4);
//iVal is 20BIT Integer Value;
iVal = HexCharToIntVal(C0);
iVal = HexCharToIntVal(C1) + iVal*16;
iVal = HexCharToIntVal(C2) + iVal*16;
iVal = HexCharToIntVal(C3) + iVal*16;
iVal = HexCharToIntVal(C4) + iVal*16;
Result[4] = IntValTo32Char((iVal shr 15) and 32);
Result[3] = IntValTo32Char((iVal shr 10) and 32);
Result[2] = IntValTo32Char((iVal shr 5) and 32);
Result[1] = IntValTo32Char((iVal shr 0) and 32);
end;
对于不足5个Char的,可以补零,同时你需要采用合适的方式标记最后补了多少个0
 
to lanyun2:谢谢你的回复,但你的程序是不正确的,你可以自己仔细试试。
 
to zjan521:36进制我见过有程序实现过的。人家要求就用36进制表示的,没办法,要求就只用0..9A..Z来表示。
这属于大数运算,16,32,64,128,265这些都比较容易实现,FGInt里就有现成的转换函数。
要是没点难度的问题就不会上来问了[:D]
 
很有创意。36进制主要用在什么地方?
 
用途很多,比如可以压缩字符
 
没有富翁做过吗?做过的给个提示也好啊。
 
哎,那我就留名等着学习吧,郁闷,还以为这个问题很简单呢
不过大虾能告诉我我想法哪里错了吗?
 
这有何难的?稍稍有些编码知识的都会弄!
 
to 大汉千秋:
可否指点一二啊,让大家来学习学习。
 
假如有个16进制数:0C0160652414C7DD4ACE9D3970DAE8E6ADF65F3167B10663BCC1998316476A728F553EA4442D40053BCFAEED663061BE6AFEC24E5EACC44A7988FBF2EDDEFB25FAB
16对应36,
16:0123456789ABCDEF
36:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
你可以设定从该数的开头开始读,如果每两位一读,两位16进制最大值为FF,对应36进制的值为V.说明至少剩4位WXYZ未用,为了进行解析,你需要编一个规则来记录每两位16进制数值之间的偏移量.即FF的偏移量为0,两位16进制最大偏移量为F.可不可以设定出规则将偏移量用
每两位16进制的数的未36进制数来表示出来,我就没工夫研究了
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2236188
 

Similar threads

回复
0
查看
848
不得闲
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部