在 c# 中等效于在 c 编程中生成的要在 URL 查询字符串中发送的“Base64”编码的加密字节字符串

Posted

技术标签:

【中文标题】在 c# 中等效于在 c 编程中生成的要在 URL 查询字符串中发送的“Base64”编码的加密字节字符串【英文标题】:Equivalent in c# for a 'Base64' Encoded string of encrypted bytes generated in c programming to be sent in URL query string 【发布时间】:2015-05-28 10:33:03 【问题描述】:

我使用了这个来自网络的代码。但是在c程序中生成的结果与c#编码(ASCII、UTF-8等)不匹配。

在 c 中处理字符以克服这个问题的最佳方法是什么?

这适用于基于 Windows 的 exe。

对于文本“Í£kúæ›Ì”

in VC I get Base64 Encoded string as "zaNr+uabzADMzMzMpGICvnj/GAA2IUEAAQAAAA=="

但在 C# 中,我会根据编码类型得到不同的结果

UTF-8 = > "K0FNMEFvdy1rK0FQb0E1aUE2QU13LQ=="
UTF-7 = > "w43Co2vDusOm4oC6w4w="

等等…… C# 中的什么编码/无编码会得到与 C 程序相同的结果。

#include <stdafx.h>
#include <locale.h>
#include "base64.h"

static const unsigned char pr2six[256] =

    /* ASCII table */
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
    64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
;

int Base64decode_len(const char *bufcoded)

    int nbytesdecoded;
    register const unsigned char *bufin;
    register int nprbytes;

    bufin = (const unsigned char *) bufcoded;
    while (pr2six[*(bufin++)] <= 63);

    nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
    nbytesdecoded = ((nprbytes + 3) / 4) * 3;

    return nbytesdecoded + 1;


int Base64decode(char *bufplain, const char *bufcoded)

    int nbytesdecoded;
    register const unsigned char *bufin;
    register unsigned char *bufout;
    register int nprbytes;

    bufin = (const unsigned char *) bufcoded;
    while (pr2six[*(bufin++)] <= 63);
    nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
    nbytesdecoded = ((nprbytes + 3) / 4) * 3;

    bufout = (unsigned char *) bufplain;
    bufin = (const unsigned char *) bufcoded;

    while (nprbytes > 4) 
    *(bufout++) =
        (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
    *(bufout++) =
        (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
    *(bufout++) =
        (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
    bufin += 4;
    nprbytes -= 4;
    

    /* Note: (nprbytes == 1) would be an error, so just ingore that case */
    if (nprbytes > 1) 
    *(bufout++) =
        (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
    
    if (nprbytes > 2) 
    *(bufout++) =
        (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
    
    if (nprbytes > 3) 
    *(bufout++) =
        (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
    

    *(bufout++) = '\0';
    nbytesdecoded -= (4 - nprbytes) & 3;
    return nbytesdecoded;


static const char basis_64[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int Base64encode_len(int len)

    return ((len + 2) / 3 * 4) + 1;


int Base64encode(char *encoded, const char *string, int len)

    int i;
    char *p;

    p = encoded;
    for (i = 0; i < len - 2; i += 3) 
    *p++ = basis_64[(string[i] >> 2) & 0x3F];
    *p++ = basis_64[((string[i] & 0x3) << 4) |
                    ((int) (string[i + 1] & 0xF0) >> 4)];
    *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
                    ((int) (string[i + 2] & 0xC0) >> 6)];
    *p++ = basis_64[string[i + 2] & 0x3F];
    
    if (i < len) 
    *p++ = basis_64[(string[i] >> 2) & 0x3F];
    if (i == (len - 1)) 
        *p++ = basis_64[((string[i] & 0x3) << 4)];
        *p++ = '=';
    
    else 
        *p++ = basis_64[((string[i] & 0x3) << 4) |
                        ((int) (string[i + 1] & 0xF0) >> 4)];
        *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
    
    *p++ = '=';
    

    *p++ = '\0';
    return p - encoded;



int main() 
   char mysrc[] = "Hello world...";

    char mysrc[] = "Í£kúæ›Ì";
    char myb64[1024] = "";
    char mydst[1024] = "";

    //Base64encode(myb64, mysrc, 28);
    Base64encode(myb64, mysrc, strlen(mysrc); //corrected
    printf("The string\n[%s]\nencodes into base64 as:\n[%s]\n", mysrc, myb64);
    printf("\n");
    Base64decode(mydst, myb64);
    printf("The string\n[%s]\ndecodes from base64 as:\n[%s]\n", myb64, mydst);

    return 0;

【问题讨论】:

添加示例以更好地解释问题 【参考方案1】:

你可以试试Encoding.GetEncoding("ISO-8859-1"),所以

Encoding encoding = Encoding.GetEncoding("ISO-8859-1");
string base64Encoded = Convert.ToBase64String(encoding.GetBytes("Í£kúæ›Ì"));

请注意,一般来说,您的问题是一个非常复杂的问题...例如,请参阅https://gcc.gnu.org/onlinedocs/cpp/Character-sets.html gcc 的有关源文件编码的页面。

请注意,此响应通常是错误的...因为问题非常复杂。 C/C++ 中的char* 更类似于未编码的字节数组,而不是字符串。 C 源文件中包含的字符串常量("something")是在源文件的编码中编码的字节数组。在 Visual Studio 中,您可以通过 File->SaveAs 选择它,然后单击 Save 按钮的小箭头 Save With Encoding。例如:

printf("%d", strlen("è"));

如果文件的编码是 Windows-1252,将打印 1,如果文件的编码是 utf-8,则打印 2

因此,如果您想在 C# 中以相同的方式进行编码,则必须执行 Encoding.GetEncoding("encodingName")(或 Encoding.UTF8,如果 C/C++ 文件是 UTF8 编码)

但这仅适用于字符串常量!

例如,如果您执行scanf("%s", str)(因此您接受来自控制台的字符串),则str 中字节的编码将是控制台的编码。如果您从 Windows 控件中获取字符串,则编码将是 Windows 的默认编码(因此在 C# 中为 Encoding.Default)。如果读取的是外部文件,那么char*就是文件的字节数,所以char*的编码就是文件的编码。

【讨论】:

我在 .net 中没有看到对 Encoding "8859-1" 的支持,我可以试试其他的吗? @Bojan 原来是Encoding.GetEncoding("ISO-8859-1")...切一块:-) @@xanatos 是的!我靠近了一点。您的代码给出了以下结果 "zaNr+uY+zA==" 但比我从 c 程序 "zaNr+uabzADMzMzMpGICvnj/GAA2IUEAAQAAAA==" 得到的要短 @Bojan 阅读扩展回复,并注意Base64encode(myb64, mysrc, 28);错误...您应该使用strlen(mysrc) 而不是28。 @Bojan 您的 C/C++ 文件很有可能实际上是 Windows-1252 编码的(所以 Encoding.GetEncoding(1252))。转到文件->另存为,单击保存按钮附近的小箭头,使用编码保存以查看确切的编码。 1252 和 8859-1 之间有非常小的差异(例如 字符,在 8859-1 中不存在)【参考方案2】:

编码

string base64Encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes("my string"));
// base64Encoded = "bXkgc3RyaW5n"

解码

string base64Decoded = Encoding.UTF8.GetString(Convert.FromBase64String(base64Encoded));
// base64Decoded = "my string"

【讨论】:

c程序不等同于C#用UTF-8编码生成的程序。

以上是关于在 c# 中等效于在 c 编程中生成的要在 URL 查询字符串中发送的“Base64”编码的加密字节字符串的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 C# 中生成的代码使用下划线? [关闭]

使用 C# 应用程序中生成的批处理文件解锁 BitLocker 驱动器

试图通过管道将 C 中生成的数据传递给 Java 类。传递变量在java中出现空白而不是有数据

使用 Selenium 在页面的 onload() 中生成的 JavaScript 警报的解决方法是啥?

使用 python 和 kivy 在 pyinstaller 中生成的 exe 不起作用

在.net项目中生成的pdb是啥文件?