Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无符号字符字符串_C++_String_Encryption - Fatal编程技术网

C++ 无符号字符字符串

C++ 无符号字符字符串,c++,string,encryption,C++,String,Encryption,这是一个有趣的例子。我正在编写一个AES加密算法,并成功地对其进行了精确加密。当我试图将结果写入文件时,麻烦就来了。我得到的文件输出不正确。十六进制值会被破坏,即使按照加密的标准,它通常也是毫无意义的 在将加密输出发送到文件之前,我对其进行了一些调试。我发现我在某处得到某种类型的溢出。当正确的十六进制值应该是9e时,我会得到ffffff9e。它只会对7F以上的十六进制值执行此操作,即扩展字符集中的字符没有得到正确处理。这在我之前的项目中也发生过,当时的问题是使用char[][]容器而不是未签名的

这是一个有趣的例子。我正在编写一个AES加密算法,并成功地对其进行了精确加密。当我试图将结果写入文件时,麻烦就来了。我得到的文件输出不正确。十六进制值会被破坏,即使按照加密的标准,它通常也是毫无意义的

在将加密输出发送到文件之前,我对其进行了一些调试。我发现我在某处得到某种类型的溢出。当正确的十六进制值应该是9e时,我会得到ffffff9e。它只会对7F以上的十六进制值执行此操作,即扩展字符集中的字符没有得到正确处理。这在我之前的项目中也发生过,当时的问题是使用char[][]容器而不是未签名的char[][]容器

我的代码使用字符串在用户界面和AES加密类之间传递加密数据。我猜std::strings不支持扩展字符集。所以我的问题是:有没有一种方法可以实例化一个无符号字符串,或者我必须找到一种方法来替换我对字符串的所有用法?

首先将您的值转换为无符号字符:

问题是您的字符恰好是有符号的,因此它的值不是您想要的字节值-您必须转换为无符号字符才能获得该值。

首先将您的值转换为无符号字符:

问题是您的字符恰好是有符号的,因此它的值不是您想要的字节值-您必须转换为无符号字符才能得到它。

std::string只是std::basic_字符串模板的一个特化,因此您可以简单地执行以下操作:

typedef std::basic_string<unsigned char> ustring;
得到你想要的

请注意,C/C++标准没有定义字符是有符号的还是无符号的变体,因此任何直接将字符强制转换为较大类型的程序都会调用实现定义的行为。

std::string只不过是std::basic_字符串模板的专门化,因此您可以简单地执行以下操作:

typedef std::basic_string<unsigned char> ustring;
得到你想要的

请注意,C/C++标准没有定义char是有符号的还是无符号的变体,因此任何直接将char强制转换为较大类型的程序都会调用实现定义的行为。

std::string实际上只是一个typedef,类似于:

namespace std { 
   typedef basic_string<char> string;
}
namespace crypto { 
   using std::string;

   class AES { 
      string data;
      // ..
    };
}
但是,您必须更改代码以使用ustring或任何您喜欢的名称,而不是std::string

根据您编写代码的方式,可能不需要编辑所有代码。特别是,如果您有以下情况:

namespace std { 
   typedef basic_string<char> string;
}
namespace crypto { 
   using std::string;

   class AES { 
      string data;
      // ..
    };
}
您可以通过仅更改using声明来更改字符串类型:

namespace unsigned_types { 
    typedef std::basic_string<unsigned char> string;
}

// ...

namespace crypto {
    using unsigned_types::string;

    class AES {
        string data;
    };
}
还要注意,模板的不同实例化是完全独立的类型,即使它们所涉及的类型是相关的,因此,您可以在char和unsigned char之间进行隐式转换,这并不意味着您可以在basic_string和basic_string之间进行匹配的隐式转换。

std::string实际上只是一个typedef,类似于:

namespace std { 
   typedef basic_string<char> string;
}
namespace crypto { 
   using std::string;

   class AES { 
      string data;
      // ..
    };
}
但是,您必须更改代码以使用ustring或任何您喜欢的名称,而不是std::string

根据您编写代码的方式,可能不需要编辑所有代码。特别是,如果您有以下情况:

namespace std { 
   typedef basic_string<char> string;
}
namespace crypto { 
   using std::string;

   class AES { 
      string data;
      // ..
    };
}
您可以通过仅更改using声明来更改字符串类型:

namespace unsigned_types { 
    typedef std::basic_string<unsigned char> string;
}

// ...

namespace crypto {
    using unsigned_types::string;

    class AES {
        string data;
    };
}

还要注意的是,模板的不同实例化是完全独立的类型,即使它们所表示的类型是相关的,因此可以在字符和无符号字符之间进行隐式转换的事实并不意味着可以在基本字符串和基本字符串之间进行匹配的隐式转换。

如何从[未签名]char到较大的有符号类型是否给出UB?较大的类型需要至少大一位,在这种情况下,无符号char的任何值都可以在较大的类型中表示,而无需修改。在这种情况下,情况就是这样。@JerryCoffin,很抱歉,我弄乱了UB和实现定义的行为。根据标准,强制转换to实现定义了一个不能表示强制转换值的有符号整数类型,我认为它是UB。我相应地修正了答案。重点不是UB和IB。问题是,任何可以用一个大小的无符号表示的值都可以用一个更大的有符号表示。@JerryCoffin啊,现在我看到了y我们的观点。但我想,它已经被我上次编辑更正了,不是吗?无论如何,如果我将一个值为0x80的字符强制转换到uint_16,我可能会得到0x0080或0xff80,这取决于编译器/平台。是的,我同意你现在的观点。如何从一个[unsigned]强制转换char到较大的有符号类型是否给出UB?较大的类型需要至少大一位,在这种情况下,无符号char的任何值都可以在较大的类型中表示,而无需进行修改
,这正是发生的事情。@JerryCoffin对不起,我搞砸了UB和实现定义的行为。根据标准,转换为不能表示转换值的有符号整数类型是由实现定义的,我认为是UB。我相应地修正了答案。重点不是UB与IB的关系,而是任何可以用一个大小的无符号表示的值都可以用一个更大的有符号表示。@JerryCoffin啊,现在我明白你的意思了。但我想,我上次编辑的时候已经更正了,不是吗?在任何情况下,如果我将一个值为0x80的字符强制转换到uint_16,我可能会得到0x0080或0xff80,这取决于编译器/平台。是的,我同意您现在的说法。这在MS Windows上经常发生。即使在mingwin和其他移植到MS Windows的Unix开发工具中,它们也被认为是已签名的。在Linux下,它类似于未签名字符,但仍然是一种单独的类型。这种情况在MS Windows上经常发生。即使在mingwin和其他移植到MS Windows的Unix开发工具中,它们也被认为是已签名的。在Linux下,它类似于未签名字符,但仍然是一种单独的类型。