संशोधित बेस 64 URL को डिकोड / एन्कोड करने के लिए कोड


113

मैं एक URL में इसे डालने के लिए डेटा को आधार बनाना और फिर इसे अपने HttpHandler के भीतर डिकोड करना चाहता हूं।

मैंने पाया है कि Base64 एनकोडिंग एक '/' वर्ण के लिए अनुमति देता है जो मेरे UriTemplate मिलान को गड़बड़ कर देगा। तब मैंने पाया कि विकिपीडिया से "URL के लिए संशोधित Base64" की एक अवधारणा है:

URL वेरिएंट के लिए एक संशोधित बेस 64 मौजूद है, जहां कोई भी पैडिंग '=' का उपयोग नहीं किया जाएगा, और मानक बेस 64 के '+' और '/' वर्ण क्रमशः '-' और '_' द्वारा प्रतिस्थापित किए जाते हैं, ताकि URL एनकोडर / डिक्रोजर का उपयोग किया जा सके अब आवश्यक नहीं है और एन्कोडेड वैल्यू की लंबाई पर कोई प्रभाव नहीं पड़ता है, रिलेशनल डेटाबेस, वेब फॉर्म और सामान्य रूप से ऑब्जेक्ट पहचानकर्ताओं में उपयोग के लिए एक ही एन्कोडेड फॉर्म को बरकरार रखता है।

.NET का उपयोग करके मैं अपने वर्तमान कोड को मूल बेस 64 एन्कोडिंग करने और "URL के लिए संशोधित बेस 64" का उपयोग करने के लिए डिकोडिंग करना चाहता हूं। क्या किसी ने ऐसा किया है?

डीकोड करने के लिए, मुझे पता है कि यह कुछ इस तरह से शुरू होता है:

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 स्टैकऑवरफ़्लो प्रविष्टि के लिए बेस 64 को गाइड देखा है , लेकिन इसकी एक ज्ञात लंबाई है और इसलिए वे अंत में आवश्यक समान संकेतों की संख्या को हार्डकोड कर सकते हैं।


@Kirk: परीक्षण किए गए गणित के साथ मेरे उत्तर को समायोजित करें।
एंथनीजजोन

जवाबों:


69

इसे सही ढंग से पैड करना चाहिए: -

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

11
बाह, तुमने मुझे हरा दिया। मैं बस अपनी पोस्ट को हटा दूंगा क्योंकि ऐसा लग रहा है कि मैंने आपकी नकल की :) :)
एरोनल्स

3
क्या यह तीन '=' वर्णों में नहीं जोड़ा जाएगा? ऐसा प्रतीत होता है कि इनमें से केवल 0, 1 या 2 होंगे।
Kirk Liemohn

1
@ किर्क: यदि यह 3 अक्षर जोड़ता है तो बेस 64 स्ट्रिंग पहले से ही भ्रष्ट है। मुझे लगता है कि यह स्ट्रिंग को मान्य करने के लिए एक अच्छा विचार होगा, इसमें केवल पात्रों की उम्मीद और लंबाई 4% होनी चाहिए! = 3.
एंथनीजोन

हममम। इसे आज़माने में, यह चाल नहीं चल रही है। अभी भी जवाब खोज रहे हैं। समान चिन्हों की संख्या ठीक से नहीं निकल रही है।
कर्क लीमोहान

2
@AnthonyWJones 'में केवल अपेक्षित और लंबाई% 4! = 1 ' अक्षर होने चाहिए , सही?
12

173

UrlTokenEncode और UrlTokenDubble तरीकों के साथ वर्ग HttpServerUtility भी चेक करें जो URL सुरक्षित Base64 एन्कोडिंग और डिकोडिंग को संभाल रहे हैं।

नोट 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);
}

पारितोषिक के लिए धन्यवाद। मैं अगली बार कोशिश करूँगा!
किर्क लीमोन्ह

12
आपकी टिप एक बहु घंटे का शानदार अंत थी और उत्तर के लिए बाल टफट सर्च। धन्यवाद
प्रागस

क्या यह प्रत्येक / और = के लिए% एन्कोडिंग का उपयोग नहीं करेगा? यह अन्य उत्तर की तरह कुशल नहीं है
जोएलफैन

नहीं, यह एक नंबर के साथ अंत में पैडिंग के लिए उपयोग किए गए समान संकेतों की जगह लेता है और प्लस और माइनस और अंडरस्कोर के साथ स्लैश करता है।
फ्रेड्रिक हाग्लंड

15
ध्यान दें कि UrlTokenEncodeकड़ाई से आधार 64url नहीं है , क्योंकि यह '0', '1' या '2' के साथ 'पैडिंग' को बदल देता है, यह निर्भर करता है कि कितने समान संकेतों ने इसे प्रतिस्थापित किया है।
लादेनज

28

टिप्पणी करने के लिए पर्याप्त बिंदु नहीं हैं, लेकिन यदि यह मदद करता है, तो कोड स्निपेट जो सुशील को दिए गए लिंक में मिला (JSON वेब सिग्नेचर ietf ड्राफ्ट) URL में पैरामीटर 64 को एक पैरामीटर के रूप में एन्कोडिंग करते समय काम करता है।

नीचे उन लोगों के लिए नकल स्निपेट जो आलसी हैं:

    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 के साथ संगत है
रजा Mortazavi

ठीक वही जो मेरे द्वारा खोजा जा रहा था! एक पुस्तकालय में खींचने के लिए बिना Xamarin के लिए वास्तव में अच्छा विकल्प।
स्लीपिंग_जेंट

19

मैं बेस 64url एन्कोडिंग के लिए एन्कोड / डिकोड करने के लिए कोड की तलाश करते समय यहां मारा जो कि प्रश्न में बताए अनुसार बेस 64 से थोड़ा अलग है।

इस दस्तावेज़ में सी # कोड स्निपेट मिला। JSON वेब सिग्नेचर ietf ड्राफ्ट


2
यह एकमात्र समाधान था जो GMail API v1 (Message.Raw) में संदेश पार्स करते समय मेरे लिए काम करता था
HeyZiko

5

स्वीकृत उत्तर की तुलना में, यहां बताया गया है कि आप मूल रूप से C # का उपयोग करके बेस 64 एनकोडेड url को डिकोड करेंगे।

डिकोड:

string codedValue = "base64encodedUrlHere";

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

शायद अगर आप अधिक विवरण प्रदान करते हैं और स्वीकार किए गए उत्तर की तुलना करते हैं, तो आपको एक उत्थान मिल सकता है - धन्यवाद
मौरिसियो ग्रेसिया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.