UUENCODE(UUE) 編碼簡介
注:UUENCODE下簡稱“UUE”,基本介紹見百度:http://baike.baidu.com/link?url=qPMUBz9X4N2C-SGRSaVgW3YQJgKF0WDB6NhSAZ6YgEYVkxsOpH99MLuyCiojqM77mcNL8klCuB8BK96CXHmqGSHe2Gjc9X6XqYLOJSOSK8W
這幾天在弄asp包裝爲Dll,嫌每次更改代碼都要編譯DLL並重裝太麻煩,遂想學AspToDll風火輪或ASPtoDLL那樣,一勞永逸的安裝個dll然後提交編碼代碼執行即可。
但現在的幾個ASP代碼加密工具都有解碼器了,有違我將ASP打包爲DLL的初衷,遂翻出來以前的幾個可逆編碼器,想改掉密碼本base64的已經有現成的講解文章了(http://blog.csdn.net/xuefeng0707/article/details/19845111),就不寫了,可是UUE的說明沒找到,於是自己用以前下載自(http://blog.csdn.net/tzwsoho和http://download.csdn.net/source/564897,注:均有BUG)的代碼研究了一下,才發現編碼表原來整的這麼簡單。
(以下爲摘抄的部分算法=====================)
Uuencode的算法很簡單,編碼時它將3個字符順序放入一個24位的緩衝區,缺字符的地方補零,然後將緩衝區截斷成爲4個部分,高位在先,每個部分6位,用下面的64個字符重新表示:
“`!”#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_”
在文件的開頭有“begin xxx
被編碼的文件名”,在文件的結尾有“end”,用來標誌Uue文件的開始和結束。編碼時,每次讀取源文件的45個字符,不足45個的用“NULL”補足爲3的整數倍(如:23補爲24),然後輸入目標文件一個ASCII爲:“32+實際讀取的字符數”的字符作爲每一行的開始。讀取的字符編碼後輸入目標文件,再輸入一個“換行符”。如果源文件被編碼完了,那麼輸入“`(ASCII爲96)”和一個“換行符”表示編碼結束。解碼時它將4個字符分別轉換爲4個6位字符後,截取有用的後六位放入一個 24 位的緩衝區,即得3個二進制代碼。
‘===================================================================
按照以上介紹和研究結果,我自己寫了一份自己好理解的算法說明:
編碼表 :用 ASCII 33 to 96
&b000001 1=33 chr(33)= !
to
&b111111 63=95 chr(95)= _
&b000000 0=96 chr(96)= `
將字符拆分爲三個一組,組成3*8位=24位,後每6位裁爲一個字符,裁爲 24位/6位=4字符,
裁得的每6位爲編碼表順序號,去碼錶查詢轉換爲對應順序號的ASCII碼 asc(裁得6位二進制數字+32)=對應字符,特例:0=96。編碼爲文件時,首行和末行加標識,表示文件名
開始 數字 文件名 (中間的數字777不知何意,只可爲數字) begin 777 uuecode.bin
文件末尾加 end 結束例:
begin 888 uuecode.bin
M`!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[ #\]^_ end
注:以上代碼複製到記事本保存爲擴展名爲 uue 的文件,可用winrar解壓得到源文件uuecode.bin
編碼每一行對應45個字節,行首用大寫字母 M 開頭,(表示後跟幾個編碼前原始字節,實際包含編碼字節爲(45/3)*4=60個編碼後字符
,asc(M)=77=45+32 ,32爲字符表起始值減1),後跟編碼完成的內容。
末行如爲不足45字節,超出部分字節數量加32轉換爲行首字符,同上,asc(剩餘字節數+32)做行首字符,到“END”標識結束。取三個字符時,如不足三個,用 0 填充剩餘位數,補足24位,編碼後如base64那樣的 = 號放末尾,這裏則用 ,chr(96)字符
字符本身在編碼表代表 0
做末尾標識字符,因爲
,有衝突,所以,必須在行首字符記錄後面的編碼串所帶的原始字符數(注:這裏如要自定義編碼規則爲純字符串編碼時,可以使用編碼表外的字符如chr(97)至chr(127)來做末尾不齊字符。僅供參考!)
同時,今天重新處理了一下base64編碼表,將其直接用一串字符串代替來查詢,如:const BASE_64_MAP_INIT = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”
對比UUE和base64編碼,發現,除了文件輸出格式略有區別外,兩種編碼的算法是完全一致的。因此,將前面 BASE_64_MAP_INIT 的值換爲UUE的碼錶,`!”#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_,同時將末尾補齊用的 = 字符換爲其他在碼錶中不存在的字符後,即可使用base64編碼解碼程序來處理UUE編碼文本!
同理自定義你自己的編碼表即可得到屬於你自己的獨一無二的加密解密代碼!如適當配合字符可逆易位編碼,效果更佳!
(以下代碼已調試對比UUE標準編碼器通過,注:因只用於純字符串編碼解碼,所以,不處理定長折行和加入行首字母)代碼摘自:(http://wang11291895.blog.163.com/blog/static/37879790200869334471/) ,並解決了大幅度的Bug,優化。
Option Explicit
'Private Const BASE_64_MAP_INIT = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
Private Const BASE_64_MAP_INIT = "`!" & """" & "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_~"
Private Base64EncMap(64) As String
Private Base64DecMap(127) As Byte
Private Sub cmd_base64De_Click()
Text1.Text = NewBase64De(Text2.Text)
End Sub
Private Sub cmd_base64En_Click()
Text2.Text = NewBase64En(Text1.Text)
End Sub
Public Function NewBase64En(ByVal plain As String) As String
If Len(plain) = 0 Then
NewBase64En = ""
Exit Function
End If
Call initCodecs
Dim ret As String, ndx As Integer, by3 As Integer
Dim first As Byte, second As Byte, third As Byte, i
Dim mAllByteIn() As Byte, inLangth As Integer
mAllByteIn() = StrConv(plain, vbFromUnicode)
inLangth = UBound(mAllByteIn) + 1 'Len(plain)
by3 = (inLangth \ 3) * 3
ndx = 1
Do While ndx <= by3
first = mAllByteIn(ndx - 1)
second = mAllByteIn(ndx + 0)
third = mAllByteIn(ndx + 1)
ret = ret & Base64EncMap((first \ 4) And 63)
ret = ret & Base64EncMap(((first * 16) And 48) + ((second \ 16) And 15))
ret = ret & Base64EncMap(((second * 4) And 60) + ((third \ 64) And 3))
ret = ret & Base64EncMap(third And 63)
ndx = ndx + 3
Loop
If by3 < inLangth Then
first = mAllByteIn(ndx - 1)
ret = ret & Base64EncMap((first \ 4) And 63)
If (inLangth Mod 3) = 2 Then
second = mAllByteIn(ndx + 0)
ret = ret & Base64EncMap(((first * 16) And 48) + ((second \ 16) And 15))
ret = ret & Base64EncMap(((second * 4) And 60)) & Base64EncMap(64) '"="
Else
ret = ret & Base64EncMap((first * 16) And 48)
ret = ret & Base64EncMap(64) & Base64EncMap(64) ' "=="
End If
End If
NewBase64En = ret
End Function
Public Function NewBase64De(ByVal scrambled As String) As String
If Len(scrambled) = 0 Then
NewBase64De = ""
Exit Function
End If
Dim realLen As Integer
Call initCodecs
realLen = Len(scrambled)
Do While Mid(scrambled, realLen, 1) = Base64EncMap(64)
realLen = realLen - 1
Loop
Dim ret() As Byte, ndx As Integer, by4 As Integer, first As Byte, second As Byte, third As Byte, fourth As Byte
Dim retLength As Integer
by4 = (realLen \ 4) * 4
ndx = 1
ReDim ret(0)
Do While ndx <= by4
first = Base64DecMap(Asc(Mid(scrambled, ndx + 0, 1)))
second = Base64DecMap(Asc(Mid(scrambled, ndx + 1, 1)))
third = Base64DecMap(Asc(Mid(scrambled, ndx + 2, 1)))
fourth = Base64DecMap(Asc(Mid(scrambled, ndx + 3, 1)))
retLength = IIf(UBound(ret) = 0, UBound(ret) - 1, UBound(ret))
ReDim Preserve ret(retLength + 3)
ret(retLength + 1) = ((first * 4) And 255) + ((second \ 16) And 3)
ret(retLength + 2) = ((second * 16) And 255) + ((third \ 4) And 15)
ret(retLength + 3) = ((third * 64) And 255) + (fourth And 63)
ndx = ndx + 4
Loop
If ndx < realLen Then
first = Base64DecMap(Asc(Mid(scrambled, ndx + 0, 1)))
second = Base64DecMap(Asc(Mid(scrambled, ndx + 1, 1)))
retLength = IIf(UBound(ret) = 0, UBound(ret) - 1, UBound(ret))
ReDim Preserve ret(retLength + 1)
ret(retLength + 1) = ((first * 4) And 255) + ((second \ 16) And 3)
If realLen Mod 4 = 3 Then
third = Base64DecMap(Asc(Mid(scrambled, ndx + 2, 1)))
retLength = UBound(ret)
ReDim Preserve ret(retLength + 1)
ret(retLength + 1) = ((second * 16) And 255) + ((third \ 4) And 15)
End If
End If
NewBase64De = StrConv(ret, vbUnicode)
End Function
Private Sub initCodecs() '初始化函數initCodecs
Dim max As Integer, idx As Integer
max = Len(BASE_64_MAP_INIT)
For idx = 0 To max - 1
Base64EncMap(idx) = Mid(BASE_64_MAP_INIT, idx + 1, 1)
Next
For idx = 0 To max - 1
Base64DecMap(Asc(Base64EncMap(idx))) = idx
Next
End Sub
源代碼下載:(http://download.csdn.net/detail/jessezappy/9707790),UUE(UUENCODE ) & Base64編碼解碼原理源代碼。可自定義編碼表(純字符串),修改編碼表即可在UUE和Base64編碼解碼之間切換,已優化解決不支持中文的BUG。
純字符串方式,不考慮定長折行和加行首字符及文件頭尾定義等,方便網頁運用,可直接移植爲ASP代碼(需要刪除AS變量類型限定)!