수정 된 base64 URL을 디코딩 / 인코딩하기위한 코드


113

base64로 데이터를 인코딩하여 URL에 넣은 다음 내 HttpHandler 내에서 디코딩하고 싶습니다.

Base64 인코딩이 내 UriTemplate 일치를 엉망으로 만드는 '/'문자를 허용 한다는 것을 발견했습니다 . 그런 다음 wikipedia에서 "URL에 대한 수정 된 Base64"개념이 있음을 발견했습니다.

URL 변형에 대해 수정 된 Base64가 존재합니다. 여기서 패딩 '='가 사용되지 않고 표준 Base64의 '+'및 '/'문자가 각각 '-'및 '_'로 대체되어 URL 인코더 / 디코더를 사용합니다. 은 더 이상 필요하지 않으며 인코딩 된 값의 길이에 영향을주지 않으므로 일반적으로 관계형 데이터베이스, 웹 양식 및 개체 식별자에서 사용하기 위해 동일한 인코딩 된 양식을 그대로 둡니다.

.NET을 사용하여 기본 base64 인코딩 및 디코딩을 수행하는 것에서 "수정 된 base64 for URL"방법을 사용하는 것으로 현재 코드를 수정하고 싶습니다. 누구든지 이것을 했습니까?

디코딩하려면 다음과 같이 시작합니다.

string base64EncodedText = base64UrlEncodedText.Replace('-', '+').Replace('_', '/');

// Append '=' char(s) if necessary - how best to do this?

// My normal base64 decoding now uses encodedText

그러나 조금 더 복잡해 보이는 끝에 '='문자를 하나 또는 두 개 추가해야합니다.

내 인코딩 로직은 좀 더 간단해야합니다.

// Perform normal base64 encoding
byte[] encodedBytes = Encoding.UTF8.GetBytes(unencodedText);
string base64EncodedText = Convert.ToBase64String(encodedBytes);

// Apply URL variant
string base64UrlEncodedText = base64EncodedText.Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');

나는 보았다 URL에 대한 Base64로에 가이 드 StackOverflow의 항목을,하지만 알려진 길이를 가지고 있으며, 따라서 그들이 마지막에 필요한 등호의 수를 하드 코딩 할 수 있습니다.


@Kirk : 테스트 된 수학으로 내 대답을 조정하십시오.
AnthonyWJones

답변:


69

이것은 올바르게 패딩해야합니다.

 base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');

11
Bah, 당신이 나를 이겼습니다. 이 : 내가 당신을 복사 거의처럼 보이는 원인 난 그냥 내 게시물을 삭제할 수 있습니다
AaronLS

3
이것은 3 개의 '='문자를 추가하지 않습니까? 이 중 0, 1 또는 2 개만있는 것으로 보입니다.
Kirk Liemohn

1
@Kirk : 3자를 추가하면 base64 문자열이 이미 손상된 것입니다. 문자열의 유효성을 검사하는 것이 좋습니다. 예상되는 문자와 길이 % 4! = 3 만 포함해야합니다.
AnthonyWJones

흠. 이것을 시도하는 것은 속임수를 쓰지 않습니다. 아직 답을 찾고 있습니다. 등호의 수가 제대로 표시되지 않습니다.
Kirk Liemohn

2
@AnthonyWJones '예상되는 문자와 길이 % 4! = 1 ' 만 포함해야합니다 .
blueling

173

또한 URL 안전 Base64 인코딩 및 디코딩을 처리하는 UrlTokenEncode 및 UrlTokenDecode 메서드를 사용하여 HttpServerUtility 클래스를 확인하십시오 .

참고 1 : 결과는 유효한 Base64 문자열이 아닙니다. URL에 대한 일부 안전하지 않은 문자가 대체됩니다.

참고 2 : 결과는 RFC4648의 base64url 알고리즘과 다릅니다.

///<summary>
/// Base 64 Encoding with URL and Filename Safe Alphabet using UTF-8 character set.
///</summary>
///<param name="str">The origianl string</param>
///<returns>The Base64 encoded string</returns>
public static string Base64ForUrlEncode(string str)
{
    byte[] encbuff = Encoding.UTF8.GetBytes(str);
    return HttpServerUtility.UrlTokenEncode(encbuff);
}
///<summary>
/// Decode Base64 encoded string with URL and Filename Safe Alphabet using UTF-8.
///</summary>
///<param name="str">Base64 code</param>
///<returns>The decoded string.</returns>
public static string Base64ForUrlDecode(string str)
{
    byte[] decbuff = HttpServerUtility.UrlTokenDecode(str);
    return Encoding.UTF8.GetString(decbuff);
}

팁 고마워. 다음에해볼 게요!
Kirk Liemohn

12
귀하의 팁은 답을 찾기 위해 여러 시간 동안 머리털을 검색하는 영광스러운 끝이었습니다. 감사합니다
Praesagus 2010

이것은 모든 / + 및 =에 대해 % 인코딩을 사용하지 않습니까? 이것은 다른 대답만큼 효율적이지
JoelFan

아니요, 끝에 패딩에 사용 된 등호를 숫자로 바꾸고 플러스와 슬래시를 마이너스와 밑줄로 대체합니다.
Fredrik Haglund

15
참고 UrlTokenEncode엄격하지 base64url 는 '0', '1'또는 '2'가 대체 얼마나 많은 등호에 따라 함께 '='패딩을 대체 같이.
ladenedge

28

설명 할 포인트는 충분하지 않지만 도움이되는 경우 제공된 링크 (JSON Web Signature ietf draft)에서 찾은 코드 스 니펫은 Base 64를 URL의 매개 변수로 인코딩 할 때 작동합니다.

게으른 사람들을 위해 아래 스 니펫을 복사했습니다.

    static string Base64UrlEncode(byte[] arg)
    {
        string s = Convert.ToBase64String(arg); // Regular base64 encoder
        s = s.Split('=')[0]; // Remove any trailing '='s
        s = s.Replace('+', '-'); // 62nd char of encoding
        s = s.Replace('/', '_'); // 63rd char of encoding
        return s;
    }

    static byte[] Base64UrlDecode(string arg)
    {
        string s = arg;
        s = s.Replace('-', '+'); // 62nd char of encoding
        s = s.Replace('_', '/'); // 63rd char of encoding
        switch (s.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: s += "=="; break; // Two pad chars
            case 3: s += "="; break; // One pad char
            default: throw new System.Exception(
              "Illegal base64url string!");
        }
        return Convert.FromBase64String(s); // Standard base64 decoder
    }

System.Web을 사용하지 않기 때문에 Xamarin과 호환됩니다.
Reza

내가 찾던 바로 그것! 라이브러리를 가져올 필요없이 Xamarin에 대한 정말 좋은 옵션입니다.
Sleeping_Giant

19

질문에서 설명한대로 base64와 약간 다른 base64url 인코딩에 대한 인코딩 / 디코딩을 수행하는 코드를 찾는 동안 여기를 클릭했습니다.

이 문서에서 C # 코드 조각을 찾았습니다. JSON 웹 서명 ietf 초안


2
이것은의 Gmail API v1에의 메시지 (Message.Raw) 구문 분석 할 때 나를 위해 일한 것이 유일한 해결책이었다
HeyZiko

5

받아 들인 답변과 비교하여 다음은 근본적으로 디코딩 하는 방법입니다. C #을 사용하여 base64로 인코딩 된 URL을 하는 .

풀다:

string codedValue = "base64encodedUrlHere";

string decoded;
byte[] buffer =  Convert.FromBase64String(codedValue);
decoded = Encoding.UTF8.GetString(buffer);

당신이 허용 대답에 자세한 내용과 비교를 제공하는 경우 어쩌면 당신은 upvote에를 얻을 수 있습니다 - 감사합니다
마우 그라시아 구티에레즈
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.