게임강의

[비베] Base64 인코딩 만드는방법

본문


문자열을 암호화하는 방식은 여러가지가 있는데 그중에 대표적으로 Base64 Encoding도 있다는 것을 잘 아실겁니다.



Base64 인코딩도 역시 암호화의 한 중류이기 때문에 수학적 원리를 사용하여 문자열을 치환하는데, 공개키를 사용하는 RSA 암호화나 행렬을 사용하는 AES 암호화보단 상당히 이해하기가 쉽습니다.



 



먼저 Base64에서 64는 2^6, 즉 6비트 단위로 문자열을 치환합니다. 하지만 일반 아스키코드가 8비트로 이루어져있다는 점을 이용하여 Base64 인코딩은 6과 8의 최소공배수인 24에서 접합점을 찾습니다.



 



예를 들어 'Man' 이란 단어를 인코딩 해볼까요?



 



M은 아스키코드로 77, 2진수로 나타내면 01001101



a는 아스키코드로 97, 2진수로 나타내면 011000001



n은 아스키코드로 110 입니다. 2진수로 나타내면 01101110 입니다.



 



세 문자의 2진수 배열을 모두 합치면



0100110101100000101101110, 총 24비트가 됩니다.



 



그럼 이 24비트들을 총 4등분, 그러니까 6비트씩 나눠줍니다.



첫 번째 배열 : 010011(10진수로 19)



두 번째 배열 : 010110(10진수로 22)



세 번째 배열 : 000101(10진수로 5)



네 번째 배열 : 101110(10진수로 46)



 



K-1.jpg?type=w740



그림 출처 : https://en.wikipedia.org/wiki/Base64



 



그럼 이제 각 배열마다 해당되는 인덱스를 Base64 Encoding Table에서 찾아줍니다.



Base64 Encoding Table : ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/



인덱스는 0부터 시작하고, A는 [0], B는 [1], C는 [2] .. 총 64개까지 있습니다.



19에 해당되는 문자는 T, 22에 해당되는 문자는 W, 5에 해당되는 문자는 F, 46에 해당되는 문자는 u로,



Man이란 문자열은 인코딩 과정을 거쳐 TWFu로 바뀌게 됩니다.



 



원래 데이터를 24bit에 채워넣는 과정에서 배열 부분(6bit로 나눠진 부분)에서 데이터가 잘린다면 그 배열의 뒷부분은 0으로 채워놓고 나머지 배열은 '='라는 시퀀스를 대입해줍니다.



 



Base64 인코딩은 몫과 나머지의 성질을 이용한 RSA 암호화와 달리 정보와 암호화 문자열 사이 1대1 대응이 성립하여 쌍방향 암호화가 가능합니다.(즉, 복호화가 가능합니다.) 그리고 앞에서 말했듯이 1대1 대응이므로 데이터를 압축하는 능력은 없습니다.



Base64 인코딩은 64bit의 정보밖에 사용하지 않으므로 서로 다른 Character Set을 사용하는 컴퓨터 사이에서 데이터 손실 없이 정보를 보낼 수 있다는 장점이 있습니다.



 



[비주얼 베이직6로 작성한 Base64 Encoding]



 



K-1.jpg?type=w740



 



Command1은 암호화 버튼



Text1은 피문자열(x of function)



Text2는 인코딩된 문자열(y of function)



 



Private Const Base64Table As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"



 



Private Function DecToBinString(intTemp As Long) As String



    If intTemp Mod 2 = 0 Then

        DecToBinString = DecToBinString(Int(intTemp / 2)) & "0"

    Else

        If intTemp = 1 Then

            DecToBinString = "1" & DecToBinString

        Else

            DecToBinString = DecToBinString(Int(intTemp / 2)) & "1"

        End If

    End If



End Function



 



Private Function BinStringToDec(strTemp As String) As Long



    Dim i As Integer

    For i = Len(strTemp) To 1 Step -1

        BinStringToDec = BinStringToDec + Int(Mid(strTemp, Len(strTemp) - i + 1, 1)) * (2 ^ (i - 1))

    Next i



End Function



 



Private Sub Command1_Click()



    Dim BinStringBuf As String

    Dim i As Integer

    Dim strResult As String

    

    For i = 1 To Len(Text1)

        BinStringBuf = BinStringBuf & Format(DecToBinString(Asc(Mid(Text1, i, 1))), "00000000")

    Next i



    Dim intRest As Integer, numOfSequence As Integer

    intRest = Len(BinStringBuf) Mod 24

    If intRest = 0 Then

        numOfSequence = 0

    Else

        numOfSequence = 3 - Int(intRest / 6)

        BinStringBuf = BinStringBuf & String(6 - (Len(BinStringBuf) Mod 6), "0")

    End If

    

    For i = 1 To Len(BinStringBuf) Step 6

        strResult = strResult & Mid(Base64Table, BinStringToDec(Mid(BinStringBuf, i, 6)) + 1, 1)

    Next i

    

    strResult = strResult & String(numOfSequence, "=")

    

    Text2 = strResult

    

End Sub



 



 



알고리즘 쪽은 심도있게 공부를 해지 못해서 코드가 조금 조잡할 수 있으니 양해 부탁드립니다...



 



[추가]



위 소스는 8Bit로 된 문자(Ascii)만 변환이 가능합니다.


댓글목록 0

등록된 댓글이 없습니다.

최근글


새댓글


  • 등록자 벼배릅 등록일 04.14
알림 0