php 的加密函数 md5,crypt,base64_encode 等使用介绍

理解不可逆与可逆转加密函数及其实例
本文深入探讨了不可逆加密函数(如MD5和crypt)与可逆转加密函数(如base64_encode和urlencode)的区别,并通过代码实例展示了它们的使用方法及其对应的解密过程。
不可逆的加密函数为:md5()、crypt() 
md5() 用来计算 MD5 哈稀。语法为:string md5(string str); 
crypt() 将字符串用 UNIX 的标准加密 DES 模块加密。这是单向的加密函数,无法解密。欲比对字符串,将已加密的字符串的头二个字符放在 salt 的参数中,再比对加密后的字符串。语法为:string crypt(string str, string [salt]); 
可逆转的加密为:base64_encode()、urlencode() 相对应的解密函数:base64_decode() 、urldecode() 

base64_encode() 将字符串以 MIME BASE64 编码。此编码方式可以让中文字或者图片也能在网络上顺利传输。语法为string base64_encode(string data); 它的解密函数为:string base64_decode(string encoded_data); 将复回原样 
urlencode() 将字符串以 URL 编码。例如空格就会变成加号。语法为:string urlencode(string str); 
它的解密函数为:string urldecode(string str); 将复回原样 

看段代码: 
.代码如下:

<?php 
define("str","墨剑"); 
echo 'md5 加密后的结果为:'.md5(str).'<br>';//md5 加密 
echo 'crypt加密后的结果为:'.crypt(str,str).'<br>';// crypt加密 
$base64encode=base64_encode(str);// base64_encode() 加密 
echo 'base64_encode加密后的结果为:'.$base64encode.'<br>'; 
echo 'base64_decode解密后的结果为:'.base64_decode($base64encode).'<br>'; //base64_decode()解密 
$urlencode=urlencode(str); //urlencode() 加密 
echo 'urlencode加密后的结果为:'.$urlencode.'<br>'; 
echo 'urldecode解密后的结果为:'.urldecode($urlencode).'<br>';//urldecode() 解密 
?> 

输出的结果为: 
md5 加密后的结果为:ea796af15c74e90faeba49576fa7984b 
crypt加密后的结果为:墨ylCzgTtYXPs 
base64_encode加密后的结果为:xKu9ow== 
base64_decode解密后的结果为:墨剑 
urlencode加密后的结果为:%C4%AB%BD%A3 
urldecode解密后的结果为:墨剑

<think> 我们需要使用Windows API中的`CryptStringToBinaryA`函数来实现Base64解码。该函数可以将Base64字符串转换为二进制数据。 步骤: 1. 首先调用`CryptStringToBinaryA`两次:第一次用于获取解码后数据的长度,第二次进行实际解码。 2. 设置标志为`CRYPT_STRING_BASE64`,表示输入是Base64字符串。同时,如果字符串没有CRLF,我们使用`CRYPT_STRING_NOCRLF`(但注意,解码时通常不需要这个标志,因为它会忽略换行符)。 3. 解码时,我们使用相同的标志,确保正确解码。 注意:Base64字符串可能包含换行符,但我们的编码函数使用了`CRYPT_STRING_NOCRLF`,因此编码结果没有换行。但为了通用性,我们也可以处理带换行的Base64字符串。不过,在解码时,`CryptStringToBinaryA`会忽略空格和换行,所以我们可以使用相同的标志。 编写函数:`base64_decode`,输入一个Base64字符串,返回一个`std::vector<BYTE>`包含解码后的二进制数据。 代码如下: </think> 下面是根据您提供的Base64编码函数实现的对应解码函数。该函数使用Windows CryptoAPI的`CryptStringToBinaryA`进行Base64解码: ```cpp // Base64解码函数 std::vector<BYTE> base64_decode(const std::string& base64_str) { DWORD dwLen = 0; std::vector<BYTE> decoded_data; try { // 第一步:获取解码后数据的长度 if (!CryptStringToBinaryA( base64_str.c_str(), // 输入Base64字符串 static_cast<DWORD>(base64_str.length()), // 字符串长度 CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, // 与编码一致的标志 nullptr, // 不需要实际数据 &dwLen, // 接收解码后的数据长度 nullptr, // 不需要跳过字符计数 nullptr // 不需要格式检查 )) { throw std::runtime_error("CryptStringToBinaryA size failed: " + std::to_string(GetLastError())); } // 第二步:分配缓冲区并执行解码 decoded_data.resize(dwLen); if (!CryptStringToBinaryA( base64_str.c_str(), static_cast<DWORD>(base64_str.length()), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, decoded_data.data(), // 输出缓冲区 &dwLen, // 输入/输出:缓冲区大小/实际解码长度 nullptr, nullptr )) { throw std::runtime_error("CryptStringToBinaryA decode failed: " + std::to_string(GetLastError())); } // 第三步:调整缓冲区到实际解码长度 decoded_data.resize(dwLen); return decoded_data; } catch (...) { // 清理资源(如果有)并重新抛出异常 throw; } } ``` ### 代码解释 1. **函数原型**: ```cpp std::vector<BYTE> base64_decode(const std::string& base64_str) ``` - 输入:Base64编码的字符串 - 输出:解码后的二进制数据(字节数组) 2. **双调用模式**: - 第一次调用`CryptStringToBinaryA`(输出缓冲区设为`nullptr`)获取解码后数据的长度 - 第二次调用执行实际解码操作 3. **标志说明**: ```cpp CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF ``` - `CRYPT_STRING_BASE64`:指定输入是Base64格式 - `CRYPT_STRING_NOCRLF`:与编码函数一致,表示字符串不含换行符 4. **缓冲区处理**: - 根据首次调用获取的长度(`dwLen`)调整vector大小 - 二次调用后再次根据实际写入长度(`dwLen`)调整vector大小 5. **错误处理**: - 所有错误都转换为`std::runtime_error` - 包含Windows错误代码(`GetLastError()`),便于调试 ### 使用方法示例 ```cpp // 在main函数中添加测试代码 try { std::string test_str = "Hello, Base64!"; // 编码测试 auto encoded = base64_encode( std::vector<BYTE>(test_str.begin(), test_str.end()) ); std::cout << "Encoded: " << encoded << std::endl; // 解码测试 auto decoded = base64_decode(encoded); std::string decoded_str(decoded.begin(), decoded.end()); std::cout << "Decoded: " << decoded_str << std::endl; } catch (const std::exception& e) { std::cerr << "Base64 error: " << e.what() << std::endl; } ``` ### 输出示例 ``` Encoded: SGVsbG8sIEJhc2U2NCE= Decoded: Hello, Base64! ``` ### 注意事项 1. **输入验证**: - 函数不验证输入是否是合法Base64字符串 - 如果输入无效,`CryptStringToBinaryA`会返回错误 2. **内存安全**: - 使用`std::vector`自动管理内存 - 避免手动内存分配和释放 3. **性能考虑**: - 双调用模式是Windows CryptoAPI的标准做法 - 对于大文件解码,可能需要分块处理 4. **填充处理**: - Base64编码使用`=`作为填充字符 - 解码时会自动处理这些填充字符 ### 相关问题 1. Base64编码中`CRYPT_STRING_NOCRLF`标志的具体作用是什么? 2. 如何修改代码使其支持包含换行符的Base64字符串解码? 3. Windows CryptoAPI与其他Base64实现(如OpenSSL)的主要区别是什么? 4. 为什么在解码过程中需要两次调用`CryptStringToBinaryA`函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值