Base64编码字符串到字节数组C#失败

时间:2016-10-19 03:33:48

标签: c# base64 decode

我们从表单体中的外部应用程序接收base64编码的字符串,下面是我们用来将字符串解码为字节数组的代码,但是我们得到了一个异常

输入字符串

  

PHBheW1lbnRSZXNwb25zZT48cmVzcG9uc2VDb2RlPjAwMDA8L3Jlc3BvbnNlQ29kZT48cmVzcG9uc2VDb2RlVGV4dD4wLVN1Y2Nlc3NmdWw8L3Jlc3BvbnNlQ29kZVRleHQ + PHJlc3BvbnNlU3VtbWFyeT5HUkVFTjwvcmVzcG9uc2VTdW1tYXJ5PjxwYXltZW50RXZlbnRJZGVudGlmaWVyPlRYTiAzNjM5PC9wYXltZW50RXZlbnRJZGVudGlmaWVyPjxMaXN0Pjxjb21wb25lbnRJRD5UWE4gMzYzOTwvY29tcG9uZW50SUQ + PGNsaWVudElEPkdPVERJU0UwNjwvY2xpZW50SUQ + PGJhbmtBdXRoQ29kZT5UOjEyMzQ8L2JhbmtBdXRoQ29kZT48YnV5bmV0VHhuSUQ + Mzc1PC9idXluZXRUeG5JRD48L0xpc3Q + PHBheW1lbnRJbnN0cnVtZW50UmVmPjwvcGF5bWVudEluc3RydW1lbnRSZWY + PG1hc2tlZENhcmROdW1iZXI + KioqKioqKioqKioqOTY4NjwvbWFza2VkQ2FyZE51bWJlcj48Y2FyZFR5cGU + TUFTVEVSQ0FSRDwvY2FyZFR5cGU + PGV4cGlyeURhdGU + MDMvMjAxNzwvZXhwaXJ5RGF0ZT48Y3VzdG9tRGF0YT4mbHQ7IVtDREFUQVsmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI_Jmd0Ow0KJmx0O1RoaXN0bGVDdXN0b21EYXRhIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiJmd0Ow0KICAmbHQ7T3JkZXJJZCZndDtCVFBQMzYzOSZsdDsvT3JkZXJJZCZndDsNCiAgJmx0O0Ftb 3VudCZndDsxMjAmbHQ7L0Ftb3VudCZndDsNCiZsdDsvVGhpc3RsZUN1c3RvbURhdGEmZ3Q7XV0mZ3Q7PC9jdXN0b21EYXRhPjwvcGF5bWVudFJlc3BvbnNlPg

异常

  

输入不是有效的Base-64字符串,因为它包含非基本64个字符,两个以上的填充字符或填充字符中的非法字符。

代码

var inputText = // use the data as shown above
byte[] decodedBytes = Convert.FromBase64String(inputText);

我想知道这有什么问题以及为什么它会抛出异常,如果我尝试在线转换器,他们可以返回正确的结果。

2 个答案:

答案 0 :(得分:0)

这是因为您的自定义数据无效。 在该Base64编码的字符串中,您有一个原始的[CDATA],很可能没有正确编码。

请注意,如果我取出字符串的前684个字符,它会正确转换为:

<paymentResponse><responseCode>0000</responseCode><responseCodeText>0-Successful</responseCodeText><responseSummary>GREEN</responseSummary><paymentEventIdentifier>TXN 3639</paymentEventIdentifier><List><componentID>TXN 3639</componentID><clientID>GOTDISE06</clientID><bankAuthCode>T:1234</bankAuthCode><buynetTxnID>375</buynetTxnID></List><paymentInstrumentRef></paymentInstrumentRef><maskedCardNumber>************9686</maskedCardNumber><cardType>MASTERCARD</cardType><expiryDate>03/2017</expiryDate><customData>&

但是当我们到达 customData 标签时,所有地狱都会松动,我想,这包含CDATA xml内容,可能不是base64编码的。

因此,要么将CDATA内容保留,要么在将其添加到最终字符串之前对其进行正确编码,以解决问题

答案 1 :(得分:0)

谢谢大家的回复。

在研究了base64编码的工作原理后,我完成了这项工作。

下面是我用来修复它的代码。

var input = new StreamReader(Request.InputStream).ReadToEnd();
        var inputText = "PHBheW1lbnRSZXNwb25zZT48cmVzcG9uc2VDb2RlPjAwMDA8L3Jlc3BvbnNlQ29kZT48cmVzcG9uc2VDb2RlVGV4dD4wLVN1Y2Nlc3NmdWw8L3Jlc3BvbnNlQ29kZVRleHQ+PHJlc3BvbnNlU3VtbWFyeT5HUkVFTjwvcmVzcG9uc2VTdW1tYXJ5PjxwYXltZW50RXZlbnRJZGVudGlmaWVyPlRYTiAzNjM5PC9wYXltZW50RXZlbnRJZGVudGlmaWVyPjxMaXN0Pjxjb21wb25lbnRJRD5UWE4gMzYzOTwvY29tcG9uZW50SUQ+PGNsaWVudElEPkdPVERJU0UwNjwvY2xpZW50SUQ+PGJhbmtBdXRoQ29kZT5UOjEyMzQ8L2JhbmtBdXRoQ29kZT48YnV5bmV0VHhuSUQ+Mzc1PC9idXluZXRUeG5JRD48L0xpc3Q+PHBheW1lbnRJbnN0cnVtZW50UmVmPjwvcGF5bWVudEluc3RydW1lbnRSZWY+PG1hc2tlZENhcmROdW1iZXI+KioqKioqKioqKioqOTY4NjwvbWFza2VkQ2FyZE51bWJlcj48Y2FyZFR5cGU+TUFTVEVSQ0FSRDwvY2FyZFR5cGU+PGV4cGlyeURhdGU+MDMvMjAxNzwvZXhwaXJ5RGF0ZT48Y3VzdG9tRGF0YT4mbHQ7IVtDREFUQVsmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI_Jmd0Ow0KJmx0O1RoaXN0bGVDdXN0b21EYXRhIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiJmd0Ow0KICAmbHQ7T3JkZXJJZCZndDtCVFBQMzYzOSZsdDsvT3JkZXJJZCZndDsNCiAgJmx0O0Ftb3VudCZndDsxMjAmbHQ7L0Ftb3VudCZndDsNCiZsdDsvVGhpc3RsZUN1c3RvbURhdGEmZ3Q7XV0mZ3Q7PC9jdXN0b21EYXRhPjwvcGF5bWVudFJlc3BvbnNlPg";
        inputText = ValidateBase64EncodedString(inputText);

        byte[] decodedBytes = Convert.FromBase64String(inputText);

        string xml = Encoding.UTF8.GetString(decodedBytes);

       private static string ValidateBase64EncodedString(string inputText)
        {
            string stringToValidate = inputText;
            stringToValidate = stringToValidate.Replace('-', '+'); // 62nd char of encoding
            stringToValidate = stringToValidate.Replace('_', '/'); // 63rd char of encoding
            switch (stringToValidate.Length % 4) // Pad with trailing '='s
            {
                case 0: break; // No pad chars in this case
                case 2: stringToValidate += "=="; break; // Two pad chars
                case 3: stringToValidate += "="; break; // One pad char
                default:
                    throw new System.Exception(
             "Illegal base64url string!");
            }

            return stringToValidate;
        }