Rust 实战练习 - 9. 文本编码,URL编码,加密解密

编解码

编程工作中,很复杂的一个环节的就是编解码和多语言。这里只讨论编解码的工作。

目标:

  • 常见文本编码的转换(GBK, Shift-JIS, UTF8, Unicode, ASCII)
  • Web中常用的编码
  • 常见的加密算法(md5, sha1, HMAC, AES/DES, RSA)

encoding/decoding

在官方的库中搜索一下:

https://docs.rs/

简单了解一下

(吐槽一下,rust官方的std库支持的太少了,啥都要第三方库! 找起来参莠不齐,这点体验不太好)

[dependencies]
encoding = "*" # 各种字符编码
urlencoding = "*" # url path 对有影响的字符进行编码
base64 = "*" # base64的支持,提供细节定制功能
rsa = "*" # pcks1,pcks8的rsa支持,还可以互相转换

code

use std::mem::size_of;
use base64::Engine;
use encoding::{all::{ASCII, EUC_JP, GB18030, GBK}, Encoding};
use base64::engine::general_purpose;

fn main() {
    println!("\r\n1. Rust内部使用UTF-8编码, char类型用4个字节.");
    let a1 = "hello, 我是Andy!🍓";
    println!("Bin: {:?}", a1.as_bytes());
    // 英文用1字符,中文用3个,emoji用4个.
    println!("{}, len: {}, chars len: {}", a1, a1.len(), a1.chars().count());
    // char 是一个 Unicode 标量值, 是除 代理代码点(0xD800 到 0xDFFF) 之外的任何 Unicode 代码点。
    // 大小始终为四个字节. 范围 0 到 0x10FFF.
    println!("char size: {}", size_of::<char>());

    println!("\r\n2. rust str to ASCII,GBK,GB18030...");
    // https://zhuanlan.zhihu.com/p/453675608
    // 编码范围从小到大: ASCII(1) => GB2312(2) => GBK(2) => GB18030(1-4)
    // UTF-8 to GBK, GB18030
    let b1 = "a 1 王 🍓";
    println!("Rust old: {:?}", b1.as_bytes());
    if let Ok(raw) = ASCII.encode(b1, encoding::EncoderTrap::Ignore) {
        println!("ASCII: {:?}", raw); // 中文和emoji不能转换
        println!("ASCII Decode: {:?}", ASCII.decode(raw.as_slice(), encoding::DecoderTrap::Ignore));
    }
    if let Ok(raw) = GBK.encode(b1, encoding::EncoderTrap::Ignore) {
        println!("GBK: {:?}", raw); // emoji不能转换
        println!("GBK Decode: {:?}", GBK.decode(raw.as_slice(), encoding::DecoderTrap::Ignore));
    }
    if let Ok(raw) = GB18030.encode(b1, encoding::EncoderTrap::Strict) {
        println!("GB18030: {:?}", raw); // 全部都能转换
        println!("GB18030 Decode: {:?}", GB18030.decode(raw.as_slice(), encoding::DecoderTrap::Ignore));
    }
    // include Shift-JIS
    if let Ok(raw) = EUC_JP.encode(b1, encoding::EncoderTrap::Ignore) {
        println!("JP 932: {:?}", raw); // emoji不能转换
        println!("JP Decode: {:?}", EUC_JP.decode(raw.as_slice(), encoding::DecoderTrap::Ignore));
    }

    println!("\r\n3. url path encode and decode...");
    let c1 = "http://www.test.com/api/get?id=123+你好-🍓";
    println!("url encode: {}", urlencoding::encode(c1)); // 所有可能影响url的字符都被编码了
    println!("url decode: {}", urlencoding::decode("%F0%9F%91%BE%20Exterminate%21").unwrap());

    println!("\r\n4. base64 encode and decode...");
    // 当输入长度不是 3 个字节的偶数倍时,规范的 base64 编码器会在末尾插入填充字符,以便输出 长度始终是 4 的倍数
    let d1 = "hello, 123, @?&=-_, 啊";
    let d1_1 = general_purpose::STANDARD.encode(d1);
    let d1_2 = general_purpose::STANDARD.decode(d1_1.clone()).unwrap();
    println!("base64 encode: {}", d1_1);
    println!("base64 decode: {}", String::from_utf8(d1_2).unwrap());
}

加密和解密

https://zhuanlan.zhihu.com/p/347114235

目前没有比较全面的库,有一个目标类似,但是没有1.0的库:https://docs.rs/cryptocol/latest/cryptocol/.

缺失的部分可以使用 https://docs.rs/rsa/latest/rsa/

非对称加密

use cryptocol::hash::{MD5, SHA1};

fn main() {
    println!("\r\n1. md5");
    let e1 = "some thing what can be any thing!";
    let mut md5= MD5::new();
    md5.digest_str(e1);
    println!("MD5  : {} - {:?}", md5.get_hash_value_in_string(), md5.get_hash_value_in_vec());
    md5.ruminate_str(2, e1); // 双重md5
    println!("MD5*2: {} - {:?}", md5.get_hash_value_in_string(), md5.get_hash_value_in_vec());

    println!("\r\n2. sha1");
    let mut sha1 = SHA1::new();
    sha1.digest_str(e1);
    println!("sha1  : {} - {:?}", sha1.get_hash_value_in_string(), sha1.get_hash_value_in_vec());
    sha1.ruminate_str(2, e1); // 双重sha1
    println!("sha1*2: {} - {:?}", sha1.get_hash_value_in_string(), sha1.get_hash_value_in_vec());
}

RSA

use rsa::{ pkcs8::{DecodePublicKey, EncodePublicKey}, RsaPublicKey};

fn main() {
    println!("\r\n1. RSA pkcs8 public key for pem");
    let pem = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtsQsUV8QpqrygsY+2+JC
Q6Fw8/omM71IM2N/R8pPbzbgOl0p78MZGsgPOQ2HSznjD0FPzsH8oO2B5Uftws04
LHb2HJAYlz25+lN5cqfHAfa3fgmC38FfwBkn7l582UtPWZ/wcBOnyCgb3yLcvJrX
yrt8QxHJgvWO23ITrUVYszImbXQ67YGS0YhMrbixRzmo2tpm3JcIBtnHrEUMsT0N
fFdfsZhTT8YbxBvA8FdODgEwx7u/vf3J9qbi4+Kv8cvqyJuleIRSjVXPsIMnoejI
n04APPKIjpMyQdnWlby7rNyQtE4+CV+jcFjqJbE/Xilcvqxt6DirjFCvYeKYl1uH
LwIDAQAB
-----END PUBLIC KEY-----";

    let public_key = RsaPublicKey::from_public_key_pem(pem).unwrap();
    println!("Public Key: {:?}", public_key);

    let pem2 = RsaPublicKey::to_public_key_pem(&public_key, rsa::pkcs8::LineEnding::CRLF).unwrap();
    println!("Public Key pem: {}", pem2); // 与pem相同

    // 公钥和私钥互相可解密对方加密的数据
    // 公钥是可以通过私钥生成的,所以公布了私钥很危险,但是公布公钥没问题
    // https://www.cnblogs.com/Dogwei/p/13412976.html
}

相关推荐

  1. Rust 实战练习 - 9. 文本编码URL编码加密解密

    2024-04-09 07:22:03       37 阅读
  2. Backend - Django URL 路由 & 重定向 & url编码解码

    2024-04-09 07:22:03       53 阅读
  3. rust编译错误解读

    2024-04-09 07:22:03       41 阅读
  4. Rust语言实现图像编码转换

    2024-04-09 07:22:03       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-09 07:22:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-09 07:22:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-09 07:22:03       82 阅读
  4. Python语言-面向对象

    2024-04-09 07:22:03       91 阅读

热门阅读

  1. 10.枚举

    10.枚举

    2024-04-09 07:22:03      38 阅读
  2. uniapp 检查更新

    2024-04-09 07:22:03       37 阅读
  3. 新型基础设施建设(新基建)

    2024-04-09 07:22:03       32 阅读
  4. golang 使用 cipher、aes 实现 oauth2 验证

    2024-04-09 07:22:03       36 阅读
  5. MySQL视图及如何导入导出

    2024-04-09 07:22:03       35 阅读
  6. 【IP层的校验和与UDP的校验和】+【FPGA实现】

    2024-04-09 07:22:03       27 阅读
  7. Prime Ring Problem(UVA 524)

    2024-04-09 07:22:03       37 阅读
  8. 在mac环境下使用shell脚本实现tree命令

    2024-04-09 07:22:03       36 阅读
  9. 【远程桌面】Microsoft Remote Desktop 4 mac

    2024-04-09 07:22:03       37 阅读
  10. TypeScript尚硅谷学习

    2024-04-09 07:22:03       29 阅读
  11. Spring Boot整合MyBatis-Plus以及实现分页

    2024-04-09 07:22:03       35 阅读
  12. vue 双向绑定

    2024-04-09 07:22:03       36 阅读