ASP/VBS任意进制转换

今天弄程序的时候,忽然注意到系统生成的文件名都好长(大概要100个字符.),如果只是为了避免名称重复,只要按时间取年月日时分秒+微秒,一般应该没有问题了,凑吧凑吧,也只能有20位左右,再为了区别,可以在前面加几个固定字符,也不会太长。

俺这人啥都好,就是爱钻研,想到这里,就不由得想这字符能不能再压缩下? --答案非常肯定。

怎么压缩呢?我知道有一个方法就是把时间(10进制表示的)转换为更高进制,一般16进制比较常用了。但是又想到日期最大是31的,16进制很亏地说,要浪费一位。那么这个31,最适合的应该是32进制了。怎么转换呢?那么多字符(10个数字+26个英文字符)肯定够了。于是动起手来。

先上代码再废话

For i=1 to 100
	a=dbHex(i,32)
	Response.Write i&"	"& a &"	"&deHex(a,32)&"<br>"
next

Const dbHexMap="123456789ABCDEFGHIJKLMNOPQRSTUV"
Function dbHex(ByVal n, H)
	If IsNumeric(n) And n>0 Then
		Dim l, i, j(), k
		l=Int(Log(n)/Log(H)+1)
		ReDim j(l-1)
		For i=l-1 To 0 step -1
			k=(H^i)
			If n>=k Then
				j(l-i-1)= Mid(dbHexMap,n\(H^i),1)
			Else
				j(l-i-1)= 0
			End If
			n=n Mod k
		Next
		dbHex=Join(j,"")
	Else
		dbHex=0
	End If
End Function

Function deHex( str, H)
	Dim i, j, l
	l=Len(str)
	j=0
	For i=1 To l
		j=j+ H^(l-i)*InStr(dbHexMap,Mid(str,i,1))
	Next
	deHex=j
End Function
测试代码从1-100转换为32进制,再转换回10进制.暂时没有问题.

至于思路,我就不多说了,函数也很简单,这里说一点小插曲,关于vbs的整除运算符。

我其实也不常用,这里要算符合数字的以n(如:32)为底的对数,我开始是用了整除

l = Log(n) \ Log(H)+1
但测试发现有偏差,怎么回事呢?

查了下手册有一句 在除法操作前,数值表达式四舍五入为 Byte、Integer 或 Long 子类型表达式。 

因为log的结果一般是有小数的,这里作整除,会先把两个参与运算的值作四舍五入,再作除法运算,再将结果取整,所以,这里得到的结果就不是我想要的了。

所以,归结一下,有些看似方便的东西,不能乱用的。

最后,别忘了最终目的(压缩文件名长度的),测试下效果

 

d=Now()
som=32
str=dbHex(Year(d),som)& dbHex(Month(d),som)&_
	dbHex(day(d),som)& dbHex(hour(d),som)&_
	dbHex(Minute(d),som)& dbHex(second(d),som)&_
	dbHex(replace(timer,".",""),som)

Response.Write str&"	"&Len(str)&"<br>"
只有12~3位了,哈哈,还可以吧?

 

下面,还是老实工作吧。。。