[已解决]如何将数字转换为36的7次方的数字字母组合,也就N进制与10进制的转换
本帖最后由 xdcysten 于 2012-6-22 10:41 编辑每一位数可代表0~1或A~Z, 字母不分大小写 ,可变数为 36, 但上了36以后逻辑就开始有点乱了,第二位要再从1一直递进直到Z完毕然后再到第三位数。
比如:0 = 0000000
1 = 0000001
10 = 000000A
——————————————————————
问题已经解决,感谢楼下的几位兄弟帮忙
10进制转N进制的,p版的代码:Func _62Hex($iValue, $iHex)
If $iHex < 2 Or $iHex > 65 Then
Return SetError(1, 0, "")
EndIf
Local Const $KEY = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+@"
Local $iMod, $sResult
While $iValue
$iMod = Mod($iValue, $iHex)
$sResult = StringMid($KEY, $iMod + 1, 1) & $sResult
$iValue = Int($iValue / $iHex)
WEnd
;Return StringFormat("(%d)%s", $iHex, $sResult)
Return $sResult
EndFunc ;==>_62HexN进制转10进制的:Func _N2Dec($iValue, $iHex)
Local Const $KEY = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-+@"
Local $iValueLen = StringLen($iValue), $sResult
If $iHex < 2 Or $iHex > StringLen($KEY) Then
Return SetError(1, 0, "")
EndIf
For $i = 1 To $iValueLen
$sResult+=(StringInStr($KEY, StringMid($iValue, $i, 1),1)-1)* ($iHex^($iValueLen-$i))
Next
Return $sResult
EndFunc ;==>_N2Dec 本帖最后由 netegg 于 2012-6-20 11:58 编辑
进制转换?这种超过10的进制转换,需要定义到底是一个数位还是两个数位,比方126,是怎么认定的,是1和26还是12和6,甚或是1,2,6 回复 2# netegg
网上查了一下,这个应该就是10进制转36进制,但这方面的有效益的算法不去从何着手,逻辑不成 回复 3# xdcysten
难倒也不是很难,就是写起来麻烦,无非是递归计算乘方和而已 Global $dic=ObjCreate("scripting.dictionary")
For $n=0 To 9
$dic($dic.count)=$n
Next
For $n=Asc("A") To Asc("Z")
$dic($dic.count)=Chr($n)
Next
$n=Int(Random(1,36^7))
;$n=72
MsgBox(0,"",$n&@TAB&_Exchange($n))
Func _Exchange($n)
$str=""
Do
$str=$dic(Mod($n,36))&$str
$n=Int($n/36)
Until $n<36
$str=$dic($n)&$str
Return $str
EndFunc试下,太大不知会不会溢出 Global $arr
For $n=0 To 9
$arr[$n]=$n
Next
For $i=Asc("A") To Asc("Z")
$arr[$n]=Chr($i)
$n+=1
Next
$n=Int(Random(1,36^7))
;$n=360
MsgBox(0,"",$n&@TAB&_Exchange($n))
Func _Exchange($n)
$str=""
Do
$str=$arr&$str
$n=Int($n/36)
Until $n<36
$str=$arr[$n]&$str
Return $str
EndFunc转换规则对应项不多,用数组实现吧 回复 6# kevinch
多谢兄弟的回答,是这个了,能问多两个问题吗
1.在0~9,A~Z, a~z 字母大小混合情况如何实现呢
2.这些组合如何能反读出来,比如:0A = 10
数学和逻辑实在不成,还望见谅,请多多指教 本帖最后由 netegg 于 2012-6-20 12:41 编辑
回复 7# xdcysten
我就说嘛,进制转换不是那么容易的,如果建立字典的话,还不如直接写个数组对应着换了
楼主,看看10进制和16进制转换的代码吧,自己试着扩展下,把里面的参数修改下
还有lz所说的混排,A,a到底是不是一样的,如果不是的话,那就不是36进制是62进制 回复 8# netegg
多谢NETEGG提醒,刚才粗俗的看了一下,如果纯计算的话,效率会有小小小慢
写数组对应我觉得效率可能会好小小
看看能不能有些前辈有更高效的算法
最好可以互换的,像:10=0A 0A=10 回复 8# netegg
对,是62进制,有时候需要这样的大小写字母数字混排,我有个想法,不知能用正则表达式来实现不? 序列和mod值修改一下就行了
转换成十进制的话逐位:对就数值*进制^(位数-1),然后累加起来就行了
MsgBox(0, "10 -> 36", _62Hex(111111111111111, 36))
Func _62Hex($iValue, $iHex)
If $iHex < 2 OR $iHex > 62 Then
Return SetError(1, 0, "")
EndIf
Local Const $KEY = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Local $iMod, $sResult
While $iValue
$iMod = Mod($iValue, $iHex)
$sResult = StringMid($KEY, $iMod + 1, 1) & $sResult
$iValue = Int($iValue / $iHex)
WEnd
Return StringFormat("(%d)%s", $iHex, $sResult)
EndFunc ;==>_62Hex
简单取余就好了。 学习了 P版这个方法还是很不错的 P版的经典。进制转换好像就是取余计算 回复 12# pusofalse
试了P版的代码,方法很是巧妙,除了32或62进制外其它的进制也可以自定义
网上查了一下,下面是用php写的进制转换,对PHP语法不熟悉,any2Dec那里只明白要先计算字符的长度以此为计算次数,bcadd=加 bcmul=乘,其它就看不明了
请问那62进制转回10进制应该怎么写?/**
* 返回一字符串,十进制 number 以 radix 进制的表示。
* @param dec 需要转换的数字
* @param toRadix 输出进制。当不在转换范围内时,此参数会被设定为 2,以便及时发现。
* @return 指定输出进制的数字
*/
function dec2Any($dec, $toRadix) {
$MIN_RADIX = 2;
$MAX_RADIX = 62;
$num62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
if ($toRadix < $MIN_RADIX || $toRadix > $MAX_RADIX) {
$toRadix = 2;
}
if ($toRadix == 10) {
return $dec;
}
// -Long.MIN_VALUE 转换为 2 进制时长度为65
$buf = array();
$charPos = 64;
$isNegative = $dec < 0; //(bccomp($dec, 0) < 0);
if (!$isNegative) {
$dec = -$dec; // bcsub(0, $dec);
}
while (bccomp($dec, -$toRadix) <= 0) {
$buf[$charPos--] = $num62[-bcmod($dec, $toRadix)];
$dec = bcdiv($dec, $toRadix);
}
$buf[$charPos] = $num62[-$dec];
if ($isNegative) {
$buf[--$charPos] = '-';
}
$_any = '';
for ($i = $charPos; $i < 65; $i++) {
$_any .= $buf[$i];
}
return $_any;
}
/**
* 返回一字符串,包含 number 以 10 进制的表示。
* fromBase 只能在 2 和 62 之间(包括 2 和 62)。
* @param number 输入数字
* @param fromRadix 输入进制
* @return十进制数字
*/
function any2Dec($number, $fromRadix) {
$num62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$dec = 0;
$digitValue = 0;
$len = strlen($number) - 1;
for ($t = 0; $t <= $len; $t++) {
$digitValue = strpos($num62, $number[$t]);
$dec = bcadd(bcmul($dec, $fromRadix), $digitValue);
}
return $dec;
}
$sol = '<br/>' . PHP_EOL;
echo any2Dec('ZZZZZZ', 62), $sol; // 56800235583
echo dec2Any('123456', 62), $sol; // w7e
echo any2Dec('w7e', 62), $sol; // 123456
页:
[1]
2