在 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# 应用程序中生成的批处理文件解锁 BitLocker 驱动器
试图通过管道将 C 中生成的数据传递给 Java 类。传递变量在java中出现空白而不是有数据
使用 Selenium 在页面的 onload() 中生成的 JavaScript 警报的解决方法是啥?