關於BASE 24 ,BASE 64原理以及實現程序


關於BASE 24 ,BASE 64原理以及實現程序

來源 https://wangye.org/blog/archives/5/

 

可能很多人聽說過Base64編碼,很少有人聽說過Base24編碼,Base24編碼主要應用在序列號生成上,其實基本的算法思想都是一樣的,只是編碼的模式有點變化。
Base64所對應的編碼表是
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
共計64位。
而Base24所對應的編碼表是
BCDFGHJKMPQRTVWXY2346789
共計24位,這里主要去掉了一些對於序列號來說不容易識別和容易混淆的字符。

具體算法網上都有介紹我就不再贅述,下面直接談怎么編碼實現吧:-)

對於Base64算法的C語言實現,大家可以參考Bob Trower的經典開源項目b64.c,網址是http://base64.sourceforge.net/。

在這里我要談的是如何用ASP進行Base64編碼,網上搜索出的一大堆算法不是太復雜就是運行不准確,其實ASP的Base64編碼可以很簡單,當然要用到服務器的一個COM組件XmlDom,具體思路是這樣的,首先創建個臨時的節點tmp,然后給結點tmp,設置datatype = “bin.base64″,這樣就可以進行相應的編解碼了,對於文本字符串的編解碼還要用ADODB.Stream進行一次編碼轉換。

Base64的ASP實現:

Class CBase64
  Private objXmlDom
  Private objXmlNode
 
  ' GetObjectParam() 這個函數實現參考了開源項目PJBlog
  Private Function GetObjectParam()
   On Error Resume Next
   Dim Temp
   GetObjectParam = "Microsoft.XMLDOM"
   Err = 0
   Dim TmpObj
   Set TmpObj = Server.CreateObject(GetObjectParam)
   Temp = Err.Number
   If Temp = 1 Or Temp = -2147221005 Then
       GetObjectParam = "Msxml2.DOMDocument.5.0"
    End If
    Err.Clear
    Set TmpObj = Nothing
   Err = 0
  End Function
 
  Private Sub Class_Initialize()
      Set objXmlDom = Server.CreateObject(GetObjectParam())
  End Sub
 
  Private Sub Class_Terminate()
      Set objXmlDom = Nothing
  End Sub
 
  Public Function encode(AnsiCode)
    encode = ""
    Set objXmlNode = objXmlDom.createElement("tmp")
    objXmlNode.datatype = "bin.base64"
    objXmlNode.nodeTypedvalue = AnsiCode
    encode = objXmlNode.Text
    Set objXmlNode = Nothing
  End Function
 
  Public Function decode(base64Code)
    On Error Resume Next
    decode = ""
    Set objXmlNode = objXmlDom.createElement("tmp")
    objXmlNode.datatype = "bin.base64"
    objXmlNode.Text = base64Code
    decode = objXmlNode.nodeTypedvalue
    Set objXmlNode = Nothing
    If Err Then
        Err.Clear
    End If
  End Function
 
  ' 以下函數編碼字符串
  Public Function encodeText(ByVal str)
    On Error Resume Next
    Dim ado, r: r = ""
    If str <> "" Then
    Set ado = Server.CreateObject("ADODB.Stream")
        With ado
            .Charset = "gb2312"
            .Type = 2
            If .State = 0 Then .Open
            .WriteText str
            .Position = 0
            .Type = 1
            r = encode(.Read(-1))
            .Close
        End With
    Set ado = Nothing
    End If
    If Err Then Err.Clear: r = ""
    encodeText = r
  End Function
 
  ' 以下函數解碼字符串
  Public Function decodeText(ByVal str)
    On Error Resume Next
    Dim ado, r: r = ""
    If str <> "" Then
    Set ado = Server.CreateObject("ADODB.Stream")
        With ado
            .Charset = "gb2312"
            .Type = 1
            If .State = 0 Then .Open
            .Write (decode(str))
            .Position = 0
            .Type = 2
            r = .ReadText(-1)
            .Close
        End With
    Set ado = Nothing
    End If
    If Err Then Err.Clear: r = ""
    decodeText = r
  End Function
End Class

 

寫到這里想起以前項目里改寫過一段Base64和16進制互轉的代碼,在這里與大家分享下。

' Base64轉16進制
Function B64ToHex(ByVal strContent)
  Dim i,strReturned, b64pad, _
       b64map, chTemp, intLocate, k , slop
  strReturned = "" : k = 0
  b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZ" &_
              "abcdefghijklmnopqrstuvwxyz0123456789+/"
  b64pad="="
  For i=0 To Len(strContent)-1
     chTemp = Mid(strContent, i+1, 1)
     If chTemp = b64pad Then Exit For
     intLocate = InStr(1, b64map, chTemp, 0)-1
     If intLocate > -1 Then
         Select Case K
           Case 0
           strReturned = strReturned &_
                             Int2Char(Int(intLocate / 4))
           slop = intLocate And 3 :  k = 1
           Case 1
           strReturned = strReturned &_
                              Int2Char( (slop * 4) Or (Int(intLocate / 16)) )
          slop = intLocate And &h0f :  k = 2
          Case 2
          strReturned = strReturned &_
                             Int2Char(slop) & Int2Char(Int(intLocate / 4))
          slop = intLocate And 3  : k=3
          Case Else
          strReturned = strReturned &_
                             Int2Char( (slop * 4) Or (Int(intLocate / 16)) ) &_
                             Int2Char(intLocate And &h0f)
          k = 0
        End Select
     End If
  Next
  If k=1 Then strReturned = strReturned & Int2Char(slop * 4)
  B64ToHex = strReturned
End Function
 
' 16進制轉Base64
Function HexToB64(ByVal strContent)
  Dim i, c, strReturned, b64map, b64pad, intLen
  b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZ" &_
             "abcdefghijklmnopqrstuvwxyz0123456789+/"
  b64pad="="
  intLen = Len(strContent)
  For i=0 To intLen-3 Step 3
      c=Clng("&h" & Mid(strContent,i+1,3))
      strReturned = strReturned &_
                         Mid(b64map, Int(c / 64 +1), 1) &_
                         Mid(b64map, (c And 63)+1, 1)
  Next
 
  If i+1=intLen Then
     c =Clng("&h" & Mid(strContent,i+1,1))
     strReturned = strReturned & Mid(b64map, c * 4 + 1, 1)
  ElseIf i+2=intLen Then
     c =Clng("&h" & Mid(strContent,i+1,2))
     strReturned = strReturned & Mid(b64map, Int(c / 4) + 1, 1) &_
                        Mid(b64map, (c And 3)*16+1, 1)        
  End If
 
  While (Len(strReturned) And 3) >0
      strReturned = strReturned & b64pad
  Wend
  HexToB64 = strReturned
End Function

 

有關Base24的代碼實現網上也有很多,這里給出兩種不同程序語言的實現供參考。

Base24的C語言實現

static const char sel[] = {
    'B','C','D','F','G',
    'H','J','K','M','P',
    'Q','R','T','V','W',
    'X','Y','2','3','4',
    '6','7','8','9', '\0'};
 
char *b24e(char *buf, unsigned char *byst, size_t sizeOfBytes)
{
    int i = 0;
    unsigned char *p = byst;
    while ((size_t)(i = (p-byst)) < sizeOfBytes) {
        buf[2*i] = sel[((*p) >> 4)];
        buf[(2*i)+1] = sel[23 - ((*p) & 0x0f)];
        p++;
    }
    buf[(2*i)+1] = '\0';
    return buf;
}
 
unsigned char *b24d(unsigned char *buf, char *str, size_t countOfChars)
{
    size_t i;
    char *p = str;
    char *loc[2];
    unsigned char n[2];
    if (countOfChars % 2)
        return NULL;
    for (i = 0; i < (countOfChars>>1); i++) {
 
        loc[0] = strchr( sel, str[2*i] );
        loc[1] = strchr( sel, str[ ( 2*i ) + 1 ] );
        if (loc[0] == NULL || loc[1] == NULL)
            return NULL;
        n[0] = (unsigned char)( loc[0] - sel );
        n[1] = 23 - (unsigned char)( loc[1] - sel );
        buf[i] = (unsigned char)((n[0] << 4) | n[1]);
    }
    return buf;
}

 

后來由於項目需要,我特地改寫了C#版。

public static class Base24
{
  private static string sel = "BCDFGHJKMPQRTVWXY2346789";
 
  public static string Encode(string Text)
  {
    int i = 0;
    int Pos = 0;
    char []Buf = new char[Text.Length<<1];
 
    while ((i = Pos) < Text.Length)
    {
        Buf[i<<1] = sel[(Text[Pos]) >> 4];
        Buf[(i<<1) + 1] = sel[23 - (Text[Pos] & 0x0F)];
        Pos++;
     }
 
        return new string(Buf);
    }
 
    public static string Decode(string Text)
    {
        if (Text.Length % 2 != 0)
            return null;
 
        int [] NPos = new int[2];
        char[] N = new char[2];
        char[] Buf = new char[Text.Length >> 1];
 
        for (int i = 0; i < (Text.Length >> 1); i++)
        {
            NPos[0] = sel.IndexOf(Text[ i<<1 ]);
            NPos[1] = 23 - sel.IndexOf(Text[(i<<1) + 1]);
            if (NPos[0] < 0 || NPos[1] < 0) {
                return null;
            }
 
            Buf[i] = ((char)((NPos[0] << 4) | NPos[1]));
        }
            return new string(Buf);
    }
}

 

=============== End
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM