입력 길이를 3으로 나눌 수없는 경우 base64 인코딩에 패딩이 필요한 이유는 무엇입니까?
base64 인코딩에서 패딩의 목적은 무엇입니까? 다음은 wikipedia에서 발췌 한 것입니다.
"인코딩 된 출력을 4 자의 정수 배수로 강제하는 데 사용할 수있는 추가 패드 문자가 할당됩니다 (또는 인코딩되지 않은 이진 텍스트가 3 바이트의 배수가 아닌 경우). 이러한 패딩 문자는 디코딩 할 때 삭제되어야하지만 입력 바이너리 길이가 3 바이트의 배수가 아닐 때 인코딩되지 않은 텍스트의 유효 길이를 계산할 수 있습니다 (패드가 아닌 마지막 문자는 일반적으로 마지막 6 비트 블록이 0이되도록 인코딩됩니다.) -최하위 비트에 패딩 된 경우 인코딩 된 스트림의 끝에 최대 두 개의 패딩 문자가 나타날 수 있습니다. "
나는 모든 문자열을 base64로 인코딩하고 base64로 인코딩 된 문자열을 디코딩 할 수있는 프로그램을 작성했습니다. 패딩으로 해결되는 문제는 무엇입니까?
패딩이 불필요하다는 결론은 옳습니다. 인코딩 된 시퀀스의 길이에서 입력 길이를 명확하게 결정할 수 있습니다.
그러나 패딩은 예를 들어 매우 간단한 네트워크 프로토콜에서 발생할 수있는 것처럼 개별 시퀀스의 길이가 손실되는 방식으로 base64로 인코딩 된 문자열이 연결되는 상황에서 유용합니다.
경우 패딩되지 문자열 연결됩니다, 각 개별 시퀀스의 끝에서 홀수 바이트의 수에 대한 정보가 손실되기 때문에 원래의 데이터를 복구하는 것은 불가능하다. 그러나 패딩 된 시퀀스를 사용하면 모호함이 없으며 시퀀스 전체를 올바르게 디코딩 할 수 있습니다.
편집 : 일러스트레이션
단어를 base64로 인코딩하고 연결하여 네트워크를 통해 보내는 프로그램이 있다고 가정합니다. "I", "AM"및 "TJM"을 인코딩하고 패딩없이 결과를 함께 끼워 전송합니다.
I
SQ
(SQ==
패딩 포함)로 인코딩AM
QU0
(QU0=
패딩 포함)로 인코딩TJM
VEpN
(VEpN
패딩 포함)로 인코딩
따라서 전송 된 데이터는 SQQU0VEpN
. 수신자 base64 I\x04\x14\xd1Q)
는 의도 한 IAMTJM
. 보낸 사람이 인코딩 된 시퀀스에서 각 단어가 끝나는 위치에 대한 정보를 파괴 했기 때문에 결과는 말도 안됩니다 . 발신자가 SQ==QU0=VEpN
대신 전송했다면 수신자는 이를 3 개의 별도 base64 시퀀스로 디코딩하여 IAMTJM
.
패딩으로 귀찮게하는 이유
왜 각 단어 앞에 정수 길이를 붙이도록 프로토콜을 설계하지 않습니까? 그러면 수신기가 스트림을 올바르게 디코딩 할 수 있으며 패딩이 필요하지 않습니다.
인코딩을 시작하기 전에 인코딩 할 데이터의 길이를 알고 있는 한 이는 좋은 생각 입니다. 하지만 말 대신 라이브 카메라에서 비디오 덩어리를 인코딩한다면 어떨까요? 각 청크의 길이를 미리 알지 못할 수도 있습니다.
프로토콜이 패딩을 사용했다면 길이를 전혀 전송할 필요가 없습니다. 데이터는 카메라에서 들어온대로 인코딩 될 수 있으며, 각 청크는 패딩으로 종료되며 수신기는 스트림을 올바르게 디코딩 할 수 있습니다.
분명히 그것은 매우 인위적인 예이지만 아마도 패딩이 일부 상황에서 왜 도움이 될 수 있는지 보여줍니다.
패딩 문자 란 무엇입니까?
패딩 문자는 길이 요구 사항을 충족하고 의미가 없습니다.
패딩의 십진수 예 : 임의의 요구 사항이 모든 문자열의 길이가 8자인 경우 숫자 640은 "00000640"이라는 의미가 없으므로 선행 0을 패딩 문자로 사용하여이 요구 사항을 충족 할 수 있습니다.
바이너리 인코딩
바이트 패러다임 : 바이트는 사실상 표준 측정 단위이며 모든 인코딩 체계는 바이트와 다시 관련되어야합니다.
Base256 은이 패러다임에 정확히 맞습니다. 1 바이트는 base256의 한 문자와 같습니다.
Base16 , 16 진수 또는 16 진수는 각 문자에 대해 4 비트를 사용합니다. 1 바이트는 2 개의 base16 문자를 나타낼 수 있습니다.
Base64 는 base256 및 base16과 달리 바이트 패러다임에 균등하게 맞지 않습니다. 모든 base64 문자는 전체 바이트보다 2 비트 짧은 6 비트로 표현할 수 있습니다.
base64 인코딩 대 바이트 패러다임을 분수로 나타낼 수 있습니다. 문자 당 6 비트, 바이트 당 8 비트 . 이 비율을 줄이면 4 자 이상 3 바이트입니다.
이 비율 (base64 문자 4 개당 3 바이트)은 base64를 인코딩 할 때 따르려는 규칙입니다. Base64 인코딩은 모든 바이트가 자체적으로 서있을 수있는 base16 및 base256과 달리 3 바이트 번들로만 측정 할 수 있습니다.
그렇다면 패딩 문자없이 인코딩이 잘 작동하더라도 패딩이 권장되는 이유 는 무엇입니까? 패딩 문자는 이러한 추가 지점이 비어 있어야하며 모호하거나 잠재적으로 불쾌한 버그를 배제해야 함을 명시 적으로 전달합니다. 패딩을 사용하면 손실 된 비트가 없다는 약속으로 base64 인코딩을 디코딩 할 수 있습니다. 패딩이 없으면 더 이상 3 바이트 번들 측정에 대한 명시적인 승인이 없으며 추가 정보 없이는 원래 인코딩의 정확한 재생을 더 이상 보장 할 수 없습니다.
예
다음은 RFC 4648 양식의 예입니다 ( http://tools.ietf.org/html/rfc4648#section-8 ).
"BASE64"함수 내의 각 문자는 1 바이트 (base256)를 사용합니다. 그런 다음이를 base64로 변환합니다.
BASE64("") = "" (No bytes used. 0%3=0.)
BASE64("f") = "Zg==" (One byte used. 1%3=1.)
BASE64("fo") = "Zm8=" (Two bytes. 2%3=2.)
BASE64("foo") = "Zm9v" (Three bytes. 3%3=0.)
BASE64("foob") = "Zm9vYg==" (Four bytes. 4%3=1.)
BASE64("fooba") = "Zm9vYmE=" (Five bytes. 5%3=2.)
BASE64("foobar") = "Zm9vYmFy" (Six bytes. 6%3=0.)
다음은 사용할 수있는 인코더입니다. http://www.motobit.com/util/base64-decoder-encoder.asp
이것은 내 이론 일 뿐이며 소스를 제공 할 수는 없지만 패딩 문자 는 디코딩 알고리즘의 일부 구현 을 가장 간단 하게 만드는 역할 만한다고 생각합니다 . 특히 알고리즘이 인코딩 된 문자열을 다음과 같이 넣으면 int[]
최종 값이 너무 길어질 수 있습니다.
패딩이 이미 입력에있는 경우 다른 작업을 수행 할 필요가 없습니다. 알고리즘은 입력을 읽고 디코딩 할 수 있습니다.
If the algorithm is not allowed to assume the padding to be present, however, and it uses int[]
-like datastructure, then it needs to manually pad the final integer before decoding, or do some extra bookkeeping on the input's original length.
I personally don't think the padding serves any purpose whatsoever anymore, but back when CPU and RAM were not quite as abundant as now this slight optimization may have mattered. I doubt it mattered that much though... a good implementation would still need to do something sensible when fed input that was truncated randomly, and that, IMO, would give the ability to process unpadded inputs at no extra cost.
'Nice programing' 카테고리의 다른 글
C #과 유사한 JavaScript에서 숫자 형식 지정 (0) | 2020.10.25 |
---|---|
패딩은 영향을주지 않습니다. (0) | 2020.10.25 |
코드에서 여백 속성 설정 (0) | 2020.10.25 |
“NoClassDefFoundError : 클래스를 초기화 할 수 없습니다.”오류 (0) | 2020.10.25 |
내 AJAX 애플리케이션에서 뒤로 버튼에 대한 호출 가로 채기 (0) | 2020.10.25 |