Skip to content

Commit adf7513

Browse files
committed
Add custom script to Encrypt/decript with example using Rhai
1 parent baa949a commit adf7513

File tree

11 files changed

+239
-8
lines changed

11 files changed

+239
-8
lines changed

Cargo.lock

Lines changed: 95 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rust_crypt"
3-
version = "1.1.0"
3+
version = "1.2.0"
44
authors = ["Abdellatif EL MIZEB <[email protected]>"]
55
edition = "2021"
66
include = ["LICENSE", "**/*.rs", "Cargo.toml"]
@@ -26,6 +26,7 @@ log = "0.4.27"
2626
serde = { version = "1.0.219", features = ["derive"] }
2727
chrono = "0.4.41"
2828
rfd = "0.15.3"
29+
rhai = "1.21.0"
2930

3031
# native:
3132
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,37 @@ It allows users to encrypt and decrypt text using configurable logic. Designed t
2323
- 🌐 Optional Web Interface using Rust + WebAssembly (Yew).
2424
- 💡 Built with simplicity in mind — ideal for learning how encryption works under the hood.
2525

26+
## 🆕 New Feature: Custom Script Encryption/Decryption
27+
You can write your own encryption and decryption logic using Rhai, an embedded scripting language for Rust.
28+
This allows you to define your own custom algorithms directly in the app, by entering a Rhai script for encryption and another for decryption.
29+
30+
Example: Simple String Reversal Script (Encrypt & Decrypt)
31+
32+
```bash
33+
let result = "";
34+
let len = text.len();
35+
while len > 0 {
36+
len -= 1;
37+
result += text[len..len+1];
38+
}
39+
result
40+
```
41+
42+
This script reverses the input string text by iterating backward over its characters and concatenating them.
43+
Use the same script for encryption and decryption, as reversing twice returns the original text.
44+
45+
### How to Use:
46+
47+
1- Select Custom Script as the encryption method.
48+
49+
2- Enter your encryption script (e.g., the reversal script above).
50+
51+
3- Enter the same script for decryption.
52+
53+
4- Enter your key if needed (can be ignored for simple scripts).
54+
55+
5- Encrypt and decrypt text or files using your custom logic.
56+
2657
## 🚀 Getting Started
2758
2859
his project use [eframe](https://github.com/emilk/egui/tree/master/crates/eframe), a framework for writing apps using [egui](https://github.com/emilk/egui/).

src/app.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct TemplateApp {
3232
encryption_key: String,
3333
current_view: CurrentView,
3434
selected_encryption: EncryptionMethod,
35+
custom_script: String,
3536
}
3637

3738
impl Default for TemplateApp {
@@ -42,6 +43,7 @@ impl Default for TemplateApp {
4243
encryption_key: "defaultkey".to_owned(),
4344
current_view: CurrentView::EncryptText,
4445
selected_encryption: EncryptionMethod::Caesar,
46+
custom_script: String::new(),
4547
}
4648
}
4749
}

src/app/encryption/custom.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use rhai::{Engine, Scope};
2+
3+
pub fn custom_encrypt(script: &str, text: &str, key: &str) -> String {
4+
let engine = Engine::new();
5+
let mut scope = Scope::new();
6+
7+
scope.push("text", text.to_string());
8+
scope.push("key", key.to_string());
9+
10+
match engine.eval_with_scope::<String>(&mut scope, script) {
11+
Ok(result) => result,
12+
Err(err) => format!("Error: {}", err),
13+
}
14+
}
15+
16+
pub fn custom_encrypt_file(input: &str, key: &str, script: &str) -> String {
17+
custom_encrypt(script, input, key)
18+
}
19+
20+
pub fn custom_decrypt(input: &str, key: &str, script: &str) -> String {
21+
let engine = Engine::new();
22+
let mut scope = Scope::new();
23+
scope.push("text", input.to_string());
24+
scope.push("key", key.to_string());
25+
26+
match engine.eval_with_scope::<String>(&mut scope, script) {
27+
Ok(result) => result,
28+
Err(e) => format!("❌ Script Error: {}", e),
29+
}
30+
}
31+
32+
pub fn custom_decrypt_file(input: &str, key: &str, script: &str) -> String {
33+
custom_decrypt(input, key, script)
34+
}

src/app/encryption/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
pub mod caesar;
22
pub mod xor;
3+
pub mod custom;
34

45
pub use caesar::{caesar_encrypt, caesar_decrypt, caesar_encrypt_file};
56
pub use xor::{xor_encrypt, xor_decrypt, xor_encrypt_file};
7+
pub use custom::{custom_encrypt, custom_encrypt_file, custom_decrypt, custom_decrypt_file};
68

79
use serde::{Deserialize, Serialize};
810

911
#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
1012
pub enum EncryptionMethod {
1113
Caesar,
1214
XOR,
15+
Custom,
1316
}

src/app/views/decrypt_file.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::app::{encryption, TemplateApp};
22
use egui::{Ui, ComboBox, RichText, TextEdit};
33
use rfd::FileDialog;
44
use std::fs;
5-
use encryption::{EncryptionMethod, caesar_decrypt, xor_decrypt};
5+
use encryption::{EncryptionMethod, caesar_decrypt, xor_decrypt, custom_decrypt_file};
66

77
pub fn decrypt_file_view(ui: &mut Ui, app: &mut TemplateApp) {
88
ui.heading(RichText::new("📂 Decrypt File").size(20.0).strong());
@@ -27,21 +27,38 @@ pub fn decrypt_file_view(ui: &mut Ui, app: &mut TemplateApp) {
2727
.selected_text(match app.selected_encryption {
2828
EncryptionMethod::Caesar => "Caesar Cipher",
2929
EncryptionMethod::XOR => "XOR Cipher",
30+
EncryptionMethod::Custom => "Custom Script",
3031
})
3132
.show_ui(ui, |ui| {
3233
ui.selectable_value(&mut app.selected_encryption, EncryptionMethod::Caesar, "Caesar Cipher");
3334
ui.selectable_value(&mut app.selected_encryption, EncryptionMethod::XOR, "XOR Cipher");
35+
ui.selectable_value(&mut app.selected_encryption, EncryptionMethod::Custom, "Custom Script");
3436
});
3537

3638
ui.add_space(10.0);
3739

40+
// Show custom script input only if custom encryption selected
41+
if app.selected_encryption == EncryptionMethod::Custom {
42+
ui.label(RichText::new("✍️ Custom Decryption Script (Rhai)").strong());
43+
ui.add(
44+
TextEdit::multiline(&mut app.custom_script)
45+
.desired_rows(10)
46+
.desired_width(ui.available_width())
47+
.hint_text("Enter your Rhai script here.\nUse variables 'text' for input and 'key' for the encryption key."),
48+
);
49+
ui.add_space(10.0);
50+
}
51+
3852
// File Selection Button
3953
if ui.button("📁 Select File to Decrypt").clicked() {
4054
if let Some(path) = FileDialog::new().pick_file() {
4155
if let Ok(data) = fs::read_to_string(&path) {
4256
let decrypted = match app.selected_encryption {
4357
EncryptionMethod::Caesar => caesar_decrypt(&data, &app.encryption_key),
4458
EncryptionMethod::XOR => xor_decrypt(&data, &app.encryption_key),
59+
EncryptionMethod::Custom => {
60+
custom_decrypt_file(&data, &app.encryption_key, &app.custom_script)
61+
}
4562
};
4663

4764
let output_path = path.with_file_name(format!(

src/app/views/decrypt_text.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::app::{encryption, TemplateApp};
22
use egui::{Ui, ComboBox, RichText, TextEdit};
3-
use encryption::{EncryptionMethod, caesar_decrypt, xor_decrypt};
4-
3+
use encryption::{EncryptionMethod, caesar_decrypt, xor_decrypt, custom_decrypt};
54

65
pub fn decrypt_text_view(ui: &mut Ui, app: &mut TemplateApp) {
76
ui.heading(RichText::new("🔓 Decrypt Text").size(20.0).strong());
@@ -26,14 +25,28 @@ pub fn decrypt_text_view(ui: &mut Ui, app: &mut TemplateApp) {
2625
.selected_text(match app.selected_encryption {
2726
EncryptionMethod::Caesar => "Caesar Cipher",
2827
EncryptionMethod::XOR => "XOR Cipher",
28+
EncryptionMethod::Custom => "Custom Script",
2929
})
3030
.show_ui(ui, |ui| {
3131
ui.selectable_value(&mut app.selected_encryption, EncryptionMethod::Caesar, "Caesar Cipher");
3232
ui.selectable_value(&mut app.selected_encryption, EncryptionMethod::XOR, "XOR Cipher");
33+
ui.selectable_value(&mut app.selected_encryption, EncryptionMethod::Custom, "Custom Script");
3334
});
3435

3536
ui.add_space(10.0);
3637

38+
// Custom Script Input (only if selected)
39+
if app.selected_encryption == EncryptionMethod::Custom {
40+
ui.label(RichText::new("📜 Custom Rhai Script").strong());
41+
ui.add(
42+
TextEdit::multiline(&mut app.custom_script)
43+
.hint_text("Example: text.replace(\" 🔐\", \"\")")
44+
.desired_rows(6)
45+
.desired_width(ui.available_width()),
46+
);
47+
ui.add_space(10.0);
48+
}
49+
3750
// Input Text
3851
ui.label(RichText::new("📝 Encrypted Input").strong());
3952
ui.add(
@@ -49,6 +62,7 @@ pub fn decrypt_text_view(ui: &mut Ui, app: &mut TemplateApp) {
4962
app.output_text = match app.selected_encryption {
5063
EncryptionMethod::Caesar => caesar_decrypt(&app.input_text, &app.encryption_key),
5164
EncryptionMethod::XOR => xor_decrypt(&app.input_text, &app.encryption_key),
65+
EncryptionMethod::Custom => custom_decrypt(&app.input_text, &app.encryption_key, &app.custom_script),
5266
};
5367
}
5468

0 commit comments

Comments
 (0)