增加wasm生成svg二维码的方法, 增加hex转base64的方法
This commit is contained in:
parent
0c35f61d70
commit
6ec2c56005
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -67,6 +67,12 @@ version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin_hashes"
|
||||
version = "0.11.0"
|
||||
@ -397,7 +403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"base64",
|
||||
"base64 0.13.1",
|
||||
"digest 0.9.0",
|
||||
"hmac-drbg",
|
||||
"libsecp256k1-core",
|
||||
@ -565,6 +571,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qrcodegen"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
@ -649,11 +661,13 @@ name = "rustwallet"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.0",
|
||||
"bitcoin_hashes",
|
||||
"ecies",
|
||||
"getrandom",
|
||||
"hex",
|
||||
"primitive-types",
|
||||
"qrcodegen",
|
||||
"secp256k1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -27,4 +27,6 @@ getrandom = { version = "0.2.7", features = ["js"]}
|
||||
ecies = {version = "0.2", default-features = false, features = ["pure"]}
|
||||
#[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-bindgen = "0.2.83"
|
||||
qrcodegen = "1.8.0"
|
||||
base64 = "0.21.0"
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
//
|
||||
|
||||
use rustwallet::{
|
||||
decrypt, encrypt, generate_sec_key, get_address, new_wallet, sign, sign_for_tran, CWallet,
|
||||
generate_sec_key, new_wallet, sign, sign_for_tran, wdecrypt, wencrypt, wget_address,
|
||||
};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
@ -33,8 +33,7 @@ macro_rules! cchar_to_str {
|
||||
|
||||
macro_rules! str_to_cchar {
|
||||
($p1:expr) => {{
|
||||
let msgkey = CString::new($p1).unwrap();
|
||||
let c_msgkey: *mut c_char = msgkey.into_raw();
|
||||
let c_msgkey = $p1.to_string();
|
||||
c_msgkey
|
||||
}};
|
||||
}
|
||||
@ -58,40 +57,42 @@ fn main() {
|
||||
let key1 = "";
|
||||
let key2 = "cd00eb0126aeed39762579ce94c90a04695ad17fbd5e79aa4e9fc4a34ba32a5";
|
||||
let private_key = generate_sec_key(
|
||||
str_to_cchar!(msg),
|
||||
str_to_cchar!(key0),
|
||||
msg.to_string(),
|
||||
key0.to_string(),
|
||||
str_to_cchar!(key1),
|
||||
str_to_cchar!(key2),
|
||||
);
|
||||
print_cchar!(private_key);
|
||||
println!("private_key=> {}", private_key);
|
||||
|
||||
let address2 = get_address(
|
||||
let address2 = wget_address(
|
||||
str_to_cchar!(msg),
|
||||
str_to_cchar!(key0),
|
||||
str_to_cchar!(key1),
|
||||
Option(key1),
|
||||
str_to_cchar!(key2),
|
||||
);
|
||||
print_cchar!(address2);
|
||||
|
||||
println!("address=> {}", address2);
|
||||
let message = "helloword";
|
||||
let msg_encrypt = encrypt(
|
||||
let msg_encrypt = wencrypt(
|
||||
str_to_cchar!(msg),
|
||||
str_to_cchar!(key0),
|
||||
str_to_cchar!(key1),
|
||||
str_to_cchar!(key2),
|
||||
str_to_cchar!(message),
|
||||
);
|
||||
print_cchar!(msg_encrypt);
|
||||
|
||||
let msg_decrypt = decrypt(
|
||||
println!("msg_encrypt=> {}", msg_encrypt);
|
||||
|
||||
let msg_decrypt = wdecrypt(
|
||||
str_to_cchar!(msg),
|
||||
str_to_cchar!(key0),
|
||||
str_to_cchar!(key1),
|
||||
str_to_cchar!(key2),
|
||||
msg_encrypt,
|
||||
);
|
||||
print_cchar!(msg_decrypt);
|
||||
let msg_decrypt = cchar_to_str!(msg_decrypt);
|
||||
assert_eq!(message, msg_decrypt);
|
||||
|
||||
println!("msg_decrypt=> {}", msg_decrypt);
|
||||
|
||||
// let tmp_cwallet2 = restore_wallet(&tmp_cwallet);
|
||||
// let address3 = get_address(&tmp_cwallet2);
|
||||
// print_cchar!(address3);
|
||||
@ -120,10 +121,3 @@ fn main() {
|
||||
// free_cwallet(fetched); // 对应 fetch_wallet()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn print_wallet(cwallet: &CWallet) {
|
||||
print_cchar!("msg=> ", cwallet.msg_key);
|
||||
print_cchar!("master key=> ", cwallet.master_key);
|
||||
print_cchar!("second key=> ", cwallet.second_key);
|
||||
print_cchar!("backup key=> ", cwallet.backup_key);
|
||||
}
|
||||
|
12
rustwallet.h
12
rustwallet.h
@ -46,3 +46,15 @@ char *sign_for_tran(const char *msg_key,
|
||||
const char *second_key,
|
||||
const char *backup_key,
|
||||
const char *msg);
|
||||
|
||||
char *encrypt(const char *msg_key,
|
||||
const char *master_key,
|
||||
const char *second_key,
|
||||
const char *backup_key,
|
||||
const char *msg);
|
||||
|
||||
char *decrypt(const char *msg_key,
|
||||
const char *master_key,
|
||||
const char *second_key,
|
||||
const char *backup_key,
|
||||
const char *msg);
|
||||
|
@ -10,17 +10,13 @@ libName=librustwallet.a
|
||||
|
||||
rm -rf ${jniLibs}
|
||||
|
||||
mkdir ${jniLibs}
|
||||
mkdir ${jniLibs}/arm64-v8a
|
||||
mkdir ${jniLibs}/armeabi-v7a
|
||||
mkdir ${jniLibs}/x86_64
|
||||
mkdir ${jniLibs}/x86
|
||||
# mkdir ${jniLibs}
|
||||
# mkdir ${jniLibs}/arm64-v8a
|
||||
# mkdir ${jniLibs}/armeabi-v7a
|
||||
# mkdir ${jniLibs}/x86_64
|
||||
# mkdir ${jniLibs}/x86
|
||||
|
||||
targetBase=~/Documents/workspace/cocos/cocos2d-x/external/android
|
||||
cp target/aarch64-linux-android/release/${libName} ${jniLibs}/arm64-v8a/${libName}
|
||||
cp target/armv7-linux-androideabi/release/${libName} ${jniLibs}/armeabi-v7a/${libName}
|
||||
cp target/x86_64-linux-android/release/${libName} ${jniLibs}/x86_64/${libName}
|
||||
cp target/i686-linux-android/release/${libName} ${jniLibs}/x86/${libName}
|
||||
targetBase=~/Documents/workspace/crypto/cocos_js/external/android
|
||||
|
||||
cp target/aarch64-linux-android/release/${libName} ${targetBase}/arm64-v8a/${libName}
|
||||
cp target/armv7-linux-androideabi/release/${libName} ${targetBase}/armeabi-v7a/${libName}
|
||||
|
331
src/lib.rs
331
src/lib.rs
@ -5,73 +5,18 @@
|
||||
// 否则导致内存泄漏
|
||||
//
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
use qr::qr_code::QR;
|
||||
use utils::str_utils::{base64_to_hex, hex_to_base64};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
mod qr;
|
||||
mod wallet;
|
||||
use wallet_impl::Wallet;
|
||||
|
||||
mod utils;
|
||||
|
||||
use crate::wallet::*;
|
||||
|
||||
// #[cfg(target_os = "android")]
|
||||
// mod android;
|
||||
macro_rules! cchar_to_str {
|
||||
($p1:expr) => {{
|
||||
let s = CStr::from_ptr($p1);
|
||||
let ps = s.to_str().unwrap();
|
||||
ps
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! cchar_to_string {
|
||||
($p1:expr) => {{
|
||||
let s = CStr::from_ptr($p1);
|
||||
let ps = s.to_str().unwrap();
|
||||
ps.to_string()
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! cchar_to_ostring {
|
||||
($p1:expr) => {{
|
||||
let s = CStr::from_ptr($p1);
|
||||
let pb = s.to_str().unwrap();
|
||||
let result = if pb.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(pb.to_string())
|
||||
};
|
||||
result
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! str_to_cchar {
|
||||
($p1:expr) => {{
|
||||
let msgkey = CString::new($p1).unwrap();
|
||||
let c_msgkey: *mut c_char = msgkey.into_raw();
|
||||
c_msgkey
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! ostr_to_cchar {
|
||||
($p1:expr) => {{
|
||||
let key = match $p1 {
|
||||
Some(val) => CString::new(val).unwrap(),
|
||||
None => CString::new("").unwrap(),
|
||||
};
|
||||
let c_key: *mut c_char = key.into_raw();
|
||||
c_key
|
||||
}};
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CWallet {
|
||||
pub msg_key: *mut c_char,
|
||||
pub master_key: *mut c_char,
|
||||
pub second_key: *mut c_char,
|
||||
pub backup_key: *mut c_char,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
// Use `js_namespace` here to bind `console.log(..)` instead of just
|
||||
@ -96,45 +41,88 @@ macro_rules! console_log {
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn new_wallet(msg: *const c_char) -> CWallet {
|
||||
let str = cchar_to_str!(msg);
|
||||
let rust_wallet = wallet_impl::Wallet::new(str);
|
||||
convert_to_cwallet(rust_wallet)
|
||||
#[wasm_bindgen]
|
||||
pub fn new_wallet(msg_key: String) -> String {
|
||||
let rust_wallet = wallet_impl::Wallet::new(&msg_key);
|
||||
rust_wallet.get_public_key().to_string()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn reset_wallet(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
) -> CWallet {
|
||||
let rust_wallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
|
||||
let rust_wallet2 = rust_wallet.reset_wallet();
|
||||
convert_to_cwallet(rust_wallet2)
|
||||
#[wasm_bindgen]
|
||||
pub fn get_public_key(
|
||||
msg_key: String,
|
||||
master_key: String,
|
||||
second_key: Option<String>,
|
||||
backup_key: Option<String>,
|
||||
) -> String {
|
||||
let rwallet = Wallet {
|
||||
msg_key,
|
||||
master_key,
|
||||
second_key,
|
||||
backup_key,
|
||||
};
|
||||
rwallet.get_public_key().to_string()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn free_cwallet(cw: CWallet) {
|
||||
drop(CString::from_raw(cw.msg_key));
|
||||
drop(CString::from_raw(cw.master_key));
|
||||
drop(CString::from_raw(cw.second_key));
|
||||
drop(CString::from_raw(cw.backup_key));
|
||||
#[wasm_bindgen]
|
||||
pub fn generate_sec_key(
|
||||
msg_key: String,
|
||||
master_key: String,
|
||||
second_key: Option<String>,
|
||||
backup_key: Option<String>,
|
||||
) -> String {
|
||||
let rwallet = Wallet {
|
||||
msg_key,
|
||||
master_key,
|
||||
second_key,
|
||||
backup_key,
|
||||
};
|
||||
rwallet.generate_sec_key()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn get_address(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
) -> *mut c_char {
|
||||
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
|
||||
let address = rwallet.get_address();
|
||||
let address_str = format!("{:?}", address);
|
||||
let c_address = CString::new(address_str).unwrap();
|
||||
c_address.into_raw()
|
||||
#[wasm_bindgen]
|
||||
pub fn sign(
|
||||
msg_key: String,
|
||||
master_key: String,
|
||||
second_key: Option<String>,
|
||||
backup_key: Option<String>,
|
||||
msg: String,
|
||||
) -> String {
|
||||
let rwallet = Wallet {
|
||||
msg_key,
|
||||
master_key,
|
||||
second_key,
|
||||
backup_key,
|
||||
};
|
||||
let signature = rwallet.sign(msg);
|
||||
let r = match signature {
|
||||
Ok(v) => v,
|
||||
Err(err) => panic!("Problem sign: {:?}", err),
|
||||
};
|
||||
r
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn sign_for_tran(
|
||||
msg_key: String,
|
||||
master_key: String,
|
||||
second_key: Option<String>,
|
||||
backup_key: Option<String>,
|
||||
msg: String,
|
||||
) -> String {
|
||||
let rwallet = Wallet {
|
||||
msg_key,
|
||||
master_key,
|
||||
second_key,
|
||||
backup_key,
|
||||
};
|
||||
|
||||
let signature = rwallet.sign_for_tran(msg);
|
||||
let (r, recid) = match signature {
|
||||
Ok((v, _recid)) => (v, _recid),
|
||||
Err(err) => panic!("Problem sign: {:?}", err),
|
||||
};
|
||||
let result = format!("{}|{}", r, recid);
|
||||
result
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@ -157,133 +145,58 @@ pub fn wget_address(
|
||||
address_str
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn generate_sec_key(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
) -> *mut c_char {
|
||||
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
|
||||
let s_key = rwallet.generate_sec_key();
|
||||
let cs_key = CString::new(s_key).unwrap();
|
||||
cs_key.into_raw()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sign(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
msg: *const c_char,
|
||||
) -> *mut c_char {
|
||||
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
|
||||
let msg_str = cchar_to_str!(msg);
|
||||
let signature = rwallet.sign(msg_str);
|
||||
let r = match signature {
|
||||
Ok(v) => v,
|
||||
Err(err) => panic!("Problem sign: {:?}", err),
|
||||
#[wasm_bindgen]
|
||||
pub fn wencrypt(
|
||||
msg_key: String,
|
||||
master_key: String,
|
||||
second_key: Option<String>,
|
||||
backup_key: Option<String>,
|
||||
msg: String,
|
||||
) -> String {
|
||||
let rwallet = Wallet {
|
||||
msg_key,
|
||||
master_key,
|
||||
second_key,
|
||||
backup_key,
|
||||
};
|
||||
str_to_cchar!(r)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sign_for_tran(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
msg: *const c_char,
|
||||
) -> *mut c_char {
|
||||
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
|
||||
let msg_str = cchar_to_str!(msg);
|
||||
let signature = rwallet.sign_for_tran(msg_str);
|
||||
let (r, recid) = match signature {
|
||||
Ok((v, _recid)) => (v, _recid),
|
||||
Err(err) => panic!("Problem sign: {:?}", err),
|
||||
};
|
||||
let result = format!("{}|{}", r, recid);
|
||||
str_to_cchar!(result)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn encrypt(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
msg: *const c_char,
|
||||
) -> *mut c_char {
|
||||
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
|
||||
let msg_str = cchar_to_str!(msg);
|
||||
let r = match rwallet.zencrypt(msg_str) {
|
||||
let r = match rwallet.zencrypt(&msg) {
|
||||
Ok(v) => v,
|
||||
Err(err) => panic!("Problem encrypt: {:?}", err),
|
||||
};
|
||||
str_to_cchar!(r)
|
||||
r
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn decrypt(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
msg: *const c_char,
|
||||
) -> *mut c_char {
|
||||
let rwallet = generate_rwallet(msg_key, master_key, second_key, backup_key);
|
||||
let msg_str = cchar_to_str!(msg);
|
||||
println!("{}", msg_str);
|
||||
let r = match rwallet.zdecrypt(msg_str) {
|
||||
#[wasm_bindgen]
|
||||
pub fn wdecrypt(
|
||||
msg_key: String,
|
||||
master_key: String,
|
||||
second_key: Option<String>,
|
||||
backup_key: Option<String>,
|
||||
msg: String,
|
||||
) -> String {
|
||||
let rwallet = Wallet {
|
||||
msg_key,
|
||||
master_key,
|
||||
second_key,
|
||||
backup_key,
|
||||
};
|
||||
let r = match rwallet.zdecrypt(&msg) {
|
||||
Ok(v) => v,
|
||||
Err(err) => panic!("Problem encrypt: {:?}", err),
|
||||
};
|
||||
str_to_cchar!(r)
|
||||
r
|
||||
}
|
||||
|
||||
unsafe fn convert_to_cwallet(rwallet: Wallet) -> CWallet {
|
||||
let c_msgkey: *mut c_char = str_to_cchar!(rwallet.msg_key);
|
||||
let c_masterkey: *mut c_char = str_to_cchar!(rwallet.master_key);
|
||||
let c_secondkey = ostr_to_cchar!(rwallet.second_key);
|
||||
let c_backupkey = ostr_to_cchar!(rwallet.backup_key);
|
||||
|
||||
let cw = CWallet {
|
||||
msg_key: c_msgkey,
|
||||
master_key: c_masterkey,
|
||||
second_key: c_secondkey,
|
||||
backup_key: c_backupkey,
|
||||
};
|
||||
cw
|
||||
#[wasm_bindgen]
|
||||
pub fn generate_qr(content: String) -> String {
|
||||
QR::parse(&content)
|
||||
}
|
||||
|
||||
// unsafe fn convert_to_rwallet(cwallet: &CWallet) -> Wallet {
|
||||
// let pmsg = cchar_to_string!(cwallet.msg_key);
|
||||
// let pm = cchar_to_string!(cwallet.master_key);
|
||||
// let second_key = cchar_to_ostring!(cwallet.second_key);
|
||||
// let backup_key = cchar_to_ostring!(cwallet.backup_key);
|
||||
// Wallet {
|
||||
// msg_key: pmsg,
|
||||
// master_key: pm,
|
||||
// second_key: second_key,
|
||||
// backup_key: backup_key
|
||||
// }
|
||||
// }
|
||||
#[wasm_bindgen]
|
||||
pub fn str_deflate(content: String) -> String {
|
||||
hex_to_base64(&content)
|
||||
}
|
||||
|
||||
unsafe fn generate_rwallet(
|
||||
msg_key: *const c_char,
|
||||
master_key: *const c_char,
|
||||
second_key: *const c_char,
|
||||
backup_key: *const c_char,
|
||||
) -> Wallet {
|
||||
let pmsg = cchar_to_string!(msg_key);
|
||||
let pm = cchar_to_string!(master_key);
|
||||
let second_key = cchar_to_ostring!(second_key);
|
||||
let backup_key = cchar_to_ostring!(backup_key);
|
||||
Wallet {
|
||||
msg_key: pmsg,
|
||||
master_key: pm,
|
||||
second_key: second_key,
|
||||
backup_key: backup_key,
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub fn str_inflate(content: String) -> String {
|
||||
base64_to_hex(&content)
|
||||
}
|
||||
|
1
src/qr/mod.rs
Normal file
1
src/qr/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod qr_code;
|
76
src/qr/qr_code.rs
Normal file
76
src/qr/qr_code.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use qrcodegen::QrCode;
|
||||
use qrcodegen::QrCodeEcc;
|
||||
use std::fs::File;
|
||||
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct QR {
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl QR {
|
||||
pub fn parse(content: &String) -> String {
|
||||
let qr = QrCode::encode_text(content, QrCodeEcc::Low).unwrap();
|
||||
QR::to_svg_string(&qr, 4)
|
||||
}
|
||||
// Returns a string of SVG code for an image depicting
|
||||
// the given QR Code, with the given number of border modules.
|
||||
// The string always uses Unix newlines (\n), regardless of the platform.
|
||||
pub fn to_svg_string(qr: &QrCode, border: i32) -> String {
|
||||
assert!(border >= 0, "Border must be non-negative");
|
||||
let mut result = String::new();
|
||||
result += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
result += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
|
||||
let dimension = qr
|
||||
.size()
|
||||
.checked_add(border.checked_mul(2).unwrap())
|
||||
.unwrap();
|
||||
result += &format!(
|
||||
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 {0} {0}\" stroke=\"none\">\n", dimension);
|
||||
result += "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n";
|
||||
result += "\t<path d=\"";
|
||||
for y in 0..qr.size() {
|
||||
for x in 0..qr.size() {
|
||||
if qr.get_module(x, y) {
|
||||
if x != 0 || y != 0 {
|
||||
result += " ";
|
||||
}
|
||||
result += &format!("M{},{}h1v1h-1z", x + border, y + border);
|
||||
}
|
||||
}
|
||||
}
|
||||
result += "\" fill=\"#000000\"/>\n";
|
||||
result += "</svg>\n";
|
||||
result
|
||||
}
|
||||
|
||||
pub fn print_qr(qr: &QrCode) {
|
||||
let border: i32 = 4;
|
||||
for y in -border..qr.size() + border {
|
||||
for x in -border..qr.size() + border {
|
||||
// 🀰 █
|
||||
let c: char = if qr.get_module(x, y) { '█' } else { ' ' };
|
||||
print!("{0}{0}", c);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
pub fn write_image(data: &String, file_path: &PathBuf) {
|
||||
let file_name = "qr.svg";
|
||||
let mut path = file_path.clone();
|
||||
path.push(file_name);
|
||||
println!("{}", path.as_path().display());
|
||||
let mut file: File = match File::create(&path) {
|
||||
Err(why) => panic!("cannot create {}", why),
|
||||
Ok(f) => f,
|
||||
};
|
||||
match file.write_all(data.as_bytes()) {
|
||||
Ok(_) => println!("write success: {}", file_name),
|
||||
Err(why) => panic!("error write file: {}", why),
|
||||
}
|
||||
}
|
||||
}
|
1
src/utils/mod.rs
Normal file
1
src/utils/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod str_utils;
|
17
src/utils/str_utils.rs
Normal file
17
src/utils/str_utils.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
|
||||
pub fn hex_to_base64(content: &str) -> String {
|
||||
let str_tmp = match hex::decode(content) {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("error decode hex str: {}", e),
|
||||
};
|
||||
general_purpose::STANDARD_NO_PAD.encode(&str_tmp)
|
||||
}
|
||||
|
||||
pub fn base64_to_hex(content: &str) -> String {
|
||||
let str_tmp = match general_purpose::STANDARD_NO_PAD.decode(content) {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("error decode base64 str: {}", e),
|
||||
};
|
||||
hex::encode(&str_tmp)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user