4

在 Windows C++ 控制台应用程序中,我想从命令行输入中读取密码。密码用于加密(以及以后的解密,可能在世界其他地方的 Windows pc 上具有不同的语言环境)。所以我担心该密码的语言环境和编码没有给出相同的数字表示。在同一台计算机或具有相同语言环境的计算机上,这显然不会产生问题。

因此,我希望能够固定编码(和规范化?)并存储为 UTF-8。此处推荐:http ://www.jasypt.org/howtoencryptuserpasswords.html (第 4 点)。

有很多与编码/unicode/UTF-8/codepages 相关的问题我没有完全(或完全没有)掌握。我摆弄了 boost:locale 和 boost::nowide,但无法弄清楚或者它在 Windows 下不起作用(不知道)。一些链接对所涉及的问题(窗口)进行了更多说明:

http://alfps.wordpress.com/2011/11/22/unicode-part-1-windows-console-io-approaches/

http://alfps.wordpress.com/2011/12/08/unicode-part-2-utf-8-stream-mode/

但是这些链接解决了相反的问题!无论底层表示如何,如何使事物看起来相同,我需要相同的底层 [bit-wise] 表示,无论它看起来如何!

所以问题是,我如何确保(我必须这样做吗?)语言环境/编码对加密的基本数据(数据)没有影响,就像 8 位整数数组一样?我不需要关心 UTF-8 或 Unicode,只需要能够恢复数据,不管是什么语言环境/编码。第一个链接有助于解释问题。

想法,C 不知道 Unicode,会在一些 C 代码帮助中链接,还是 C++ 会再次改变它?或者将输入限制为“ASCII”字符(我知道在 Windows 上不存在)总是,就像在“任何 Windows 计算机上”一样)有效?

接受的解决方案:

void EncryptFileNames ( const boost::filesystem::path& p, const std::string& pw );

int main ( int argc, char **argv ) // No checking
{
    // Call with encrypt.exe c:\tmp pässwörd

    boost::nowide::args a ( argc, argv ); // Fix arguments - make them UTF-8

    boost::filesystem::path p ( argv [ 1 ] );

    EncryptFileNames ( p, boost::locale::normalize ( argv [ 2 ], boost::locale::norm_nfc, std::locale ( ) ) );

    return 0;
}

感谢所有贡献者。

PS:对于加密,我使用带有 VS2008SP1 和 Boost(没有 ICU 后端)的 Crypto++。

4

2 回答 2

2

如果您的应用程序是用 编译的_UNICODE,那么只需调用WideCharToMultiByteUTF-8 代码页来获取 UTF-8。如果您的应用程序未使用 编译_UNICODE,请调用MultiByteToWideChar以从您的 ACP 字节中获取 UTF-16,然后调用WideCharToMultiByte以获取 UTF-8。

由于您添加的代码显示 std::string,因此数据可能位于系统的 ACP 中。所以这里的食谱会起作用。现在,有很多方便的 API 用于此目的,例如mbtowcs. 不要被“MB”分心。这只是 Windows 对“不是 UTF-16”的说法。

于 2012-09-08T12:52:59.443 回答
-4

首先,UTF-8 是一条红鲱鱼。要国际化,您必须使用国际字符集,只有一个值得考虑,它被称为 Unicode。如何在程序中表示 Unicode(即如何编码)取决于您,只要编码可以表示所有 Unicode 就没有问题。您可以选择 UTF-8,但由于您在 Windows 上工作,因此选择 Windows 内部使用的编码 UTF-16 似乎是合理的。正如 bmargulies 所说,您可以使用 MultiByteToWideChar 从本地表示(即本地代码页)到 UTF-16。我认为不需要执行额外的步骤并从 UTF-16 生成 UTF-8,但如果你想这样做,你可以使用 WideCharToMultiByte。

于 2012-09-08T13:43:06.443 回答