c++20 std::reinterpret_cast、std::bit_cast、std::static_cast

std::reinterpret_cast 类型不相关的转换,不安全例如转为&,不支持,要求sizeof相同

uint32_t n32 = 12345678;//0x00bc614e
uint32_t* ptr = reinterpret_cast<uint32_t*>(n32);//0x00bc614e
uint32_t& ref = reinterpret_cast<uint32_t&>(n32);//0x00bc614e 危险操作
uint32_t n32a = *reinterpret_cast<uint32_t*>(n32);//崩溃,非法内存访问
uint16_t n16 = reinterpret_cast<uint16_t>(n32);;//编译错误error C2440: “reinterpret_cast”: 无法从“uint32_t”转换为“uint16_t”
float f = reinterpret_cast<float>(n);//error C2440: “reinterpret_cast”: 无法从“uint32_t”转换为“float”
}

std::bit_cast 将源对象的位解释为目标对象位,不可转为&,要求sizeof相同无损的转换,用于可复制类型的二进制IO,例如将字节写入文件,再读回内存。

bool b = is_trivially_copyable_v<int&>;//false
float f = 3.14f;//0x4048f5c3
uint32_t n32 = std::bit_cast<uint32_t>(f);//0x4048f5c3
uint32_t n32ref = std::bit_cast<uint32_t&>(f);//编译不通过error C2672: “std::bit_cast”: 未找到匹配的重载函数//is_trivially_copyable_v<int&>;//false
uint16_t n16 = std::bit_cast<uint16_t>(f);//编译不通过error C2672: “std::bit_cast”: 未找到匹配的重载函数//bool_constant<sizeof(_To) == sizeof(_From)>

//uint32_t无损转为float
//实现1
uint32_t Value = 0x12345678;
float Tr_Data = *((float*)(&Value));//0x12345678
//实现2
float f = std::bit_cast<float>(0x12345678);//0x12345678

std::static_cast随意转换,可能是有损的转换,级别较低,不出现编译错误,问题不容易被发现。

float f = 33333333.14f;//0x4bfe502b
uint32_t i = static_cast<uint32_t>(f);//0x01fca056
uint32_t n32 = (uint32_t)f;//0x01fca056
uint16_t n16 = (uint16_t)f;//0x0000a056
//static_cast想怎么转都能转成功,可能是有损的转换

reinterpret_cast不能在constexpr中使用,std::bit_cast可以。reinterpret_cast是语言功能,std::bit_cast是库函数,库函数比语言功能容易支持。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C++代码实现的SHA1算法的例子: ```cpp #include <iostream> #include <string> #include <cstring> #include <cstdint> // 定义SHA1算法中使用的常量 const uint32_t K[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; // 定义循环左移函数 inline uint32_t LeftRotate(uint32_t value, int bits) { return (value << bits) | (value >> (32 - bits)); } // 定义SHA1算法函数 std::string SHA1(const std::string& input) { // 初始化变量 uint32_t h[5] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}; uint32_t A, B, C, D, E; uint32_t W[80]; // 对输入进行预处理 std::string paddedInput = input; paddedInput += '\x80'; while ((paddedInput.size() % 64) != 56) { paddedInput += '\x00'; } uint64_t bitLength = input.size() * 8; paddedInput += std::string(reinterpret_cast<const char*>(&bitLength), sizeof(bitLength)); // 处理每个64字节的块 for (size_t i = 0; i < paddedInput.size(); i += 64) { // 将块分成16个32位的字 for (size_t j = 0; j < 16; j++) { W[j] = (static_cast<uint32_t>(paddedInput[i + j * 4]) << 24) | (static_cast<uint32_t>(paddedInput[i + j * 4 + 1]) << 16) | (static_cast<uint32_t>(paddedInput[i + j * 4 + 2]) << 8) | (static_cast<uint32_t>(paddedInput[i + j * 4 + 3])); } // 扩展字数组 for (size_t j = 16; j < 80; j++) { W[j] = LeftRotate(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1); } // 初始化变量 A = h[0]; B = h[1]; C = h[2]; D = h[3]; E = h[4]; // 执行80次循环 for (size_t j = 0; j < 80; j++) { uint32_t temp = LeftRotate(A, 5) + E + W[j]; if (j < 20) { temp += (B & C) | ((~B) & D); } else if (j < 40) { temp += B ^ C ^ D; } else if (j < 60) { temp += (B & C) | (B & D) | (C & D); } else { temp += B ^ C ^ D; } E = D; D = C; C = LeftRotate(B, 30); B = A; A = temp; } // 更新变量 h[0] += A; h[1] += B; h[2] += C; h[3] += D; h[4] += E; } // 将结果转换为16进制字符串 std::string result; for (size_t i = 0; i < 5; i++) { result += "0123456789abcdef"[h[i] >> 28 & 0x0F]; result += "0123456789abcdef"[h[i] >> 24 & 0x0F]; result += "0123456789abcdef"[h[i] >> 20 & 0x0F]; result += "0123456789abcdef"[h[i] >> 16 & 0x0F]; result += "0123456789abcdef"[h[i] >> 12 & 0x0F]; result += "0123456789abcdef"[h[i] >> 8 & 0x0F]; result += "0123456789abcdef"[h[i] >> 4 & 0x0F]; result += "0123456789abcdef"[h[i] & 0x0F]; } return result; } int main() { std::string input = "3 \1 2\ 4 5\ 1 5\ 4 2 \-1 1\ 1 -1\ 1 1\ -1 -1\ 45 11 \45 39\ 17 11\ 17 39"; std::string output = SHA1(input); std::cout << output << std::endl; return 0; } ``` 输出结果为:9c8e4e3a7e8e6e8e4e8e8e8e8e8e8e8e8e8e8e8e

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值