Skip to content

Commit

Permalink
Add benchmark and Update to crates.io
Browse files Browse the repository at this point in the history
  • Loading branch information
Metaphorme committed Nov 6, 2024
1 parent bf92d69 commit 1fb6264
Show file tree
Hide file tree
Showing 9 changed files with 756 additions and 305 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
/target
/.idea

# Example of big file
/tests/win98.iso
75 changes: 72 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 23 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
[package]
name = "ezcheck"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
description = "An easy tool to calculate and check hash."
repository = "https://github.com/Metaphorme/ezcheck"
documentation = "https://docs.rs/ezcheck"
readme = "README.md"
authors = ["Heqi Liu [email protected]"]
license-file = "LICENSE"

# MSRV
rust-version = "1.71.0"

[dependencies]
md2 = { version = "0.10" }
md4 = { version = "0.10" }
md-5 = { version = "0.10" }
sha1 = { version = "0.10" }
sha2 = { version = "0.10" }
digest = { version = "0.10" }
clap = { version = "4.5.20", features = ["derive"]}
md2 = { version = "0.10", optional = true }
md4 = { version = "0.10", optional = true }
md-5 = { version = "0.10", optional = true }
sha1 = { version = "0.10", optional = true }
sha2 = { version = "0.10", optional = true }
digest = { version = "0.10", optional = true }
ring = { version = "0.17" , optional = true }
clap = { version = "4.5", features = ["derive"]}

[features]
default = []
hashes_backend = ["md2", "md4", "md-5", "sha1", "sha2", "digest"]
ring_backend = ["ring"]
73 changes: 48 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
# ezcheck

ezcheck(easy check) is an ergonomic, standard-output command-line tool for calculating, comparing, and verifying the hashes of strings and files.
ezcheck(easy check) is an ergonomic, standard-output command-line tool for calculating, comparing, and verifying the hash of strings and files.

ezcheck supports a lot of hash algorithm: MD2(Unsafe), MD4(Unsafe), MD5(Unsafe), SHA1(Unsafe), SHA224, SHA256, SHA384, SHA512. Although many of the hash algorithms are proven to be insecure, ezcheck still provides them for maximum compatibility, but it does not recommend users continue to use them.
ezcheck have two backends: [ring](https://docs.rs/ring) and [hashes](https://docs.rs/hashes), and you can only choose one of them. The main differences between them are:

| Features | ring | hashes |
|----------------------|------------------------------------------------------------|-----------------------------------------------------------------|
| Speed | Fast | About 10 times slower than ring. |
| Supported algorithms | SHA256, SHA384, SHA512, SHA512/256 | MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, SHA512/256 |
| Implement languages | Assembly, Rust, C and etc.. | Rust |
| Compatibility | May not work on every machine with different architecture. | Works well with Rust. |

⚠️ Please notice that although ezcheck(hashes backend) supports a lot of hash algorithms, `MD2`, `MD4`, `MD5`, `SHA1` are proven to be **insecure**. ezcheck still provides them for maximum compatibility, but **it does not recommend users continue to use them**.

## Build

### Requirements

* [Rust](https://www.rust-lang.org/)
* [Rust 1.71.0+](https://www.rust-lang.org/)

### Build

```bash
$ git clone https://github.com/Metaphorme/ezcheck
$ cd ezcheck
$ cargo build --release
$ # Choose one from ring backend or hashes backend
$ # ring backend
$ cargo build --release --features ring_backend
$ # hashes backend
$ cargo build --release --features hashes_backend
$
$ ./target/release/ezcheck --version
```

### Run tests

```bash
$ cargo test
$ cargo test --features ring_backend # ring backend
$ cargo test --features hashes_backend # hashes backend
```

## Usage

Supported hash algorithms:
* MD2(Unsafe)
* MD4(Unsafe)
* MD5(Unsafe)
* SHA1(Unsafe)
* SHA224
* SHA256
* SHA384
* SHA512
Supported hash algorithms of different backends:

| ring | hashes |
|------------|------------|
| | MD2 |
| | MD4 |
| | MD5 |
| | SHA1 |
| | SHA224 |
| SHA256 | SHA256 |
| SHA384 | SHA384 |
| SHA512 | SHA512 |
| SHA512 | SHA512 |
| SHA512/256 | SHA512/256 |

### Calculate

Expand Down Expand Up @@ -76,11 +96,10 @@ $ ezcheck compare sha256 -t "Hello" -c 085f8db32271fe25f561a6fc938b2e264306ec304
SHA256 FAILED Current Hash: 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

# Auto detect hash algorithm
$ ezcheck compare -f image.jpg -c cb74bb502cc0949aad5cd838f91f0623
INFO: Hash Algorithm could be MD2, MD4, MD5
MD2 FAILED Current Hash: 10329710371ab70392948fcef544f728
MD4 FAILED Current Hash: bebc102992450c68e5543383889e27c9
MD5 OK
$ ezcheck compare -f image.jpg -c bebc102992450c68e5543383889e27c9
INFO: Hash Algorithm could be MD5, MD4, MD2
MD5 FAILED Current Hash: cb74bb502cc0949aad5cd838f91f0623
MD4 OK
```

### Check
Expand All @@ -106,23 +125,27 @@ $ ezcheck check sha256 -c sha256sum.txt
image.jpg: SHA256 OK

# Auto detect hash algorithm
$ cat sha256sum.txt
9ec44ac67ab1e1c98fe0406478d5297d 滕王阁序.txt
bebc102992450c68e5543383889e27c9 image.jpg
$ ezcheck check -c sha256sum.txt
滕王阁序.txt: SHA256 OK
image.jpg: SHA256 OK
滕王阁序.txt: MD5 FAILED Current Hash: 07c4e6a2c2db5f2d3a8998a3dba84a96
滕王阁序.txt: MD4 OK
image.jpg: MD5 FAILED Current Hash: cb74bb502cc0949aad5cd838f91f0623
image.jpg: MD4 OK

# Actually, ezcheck supports various algorithm in the same check file in auto detect.
# 🤔 But why this happens?
$ cat sha256sum.txt
00691413c731ee37f551bfaca6a34b8443b3e85d7c0816a6fe90aa8fc8eaec95 滕王阁序.txt
4c03795a6bca220a68eae7c4f136d6247d58671e074bccd58a3b9989da55f56f *image.jpg
cb74bb502cc0949aad5cd838f91f0623 image.jpg
9ec44ac67ab1e1c98fe0406478d5297d 滕王阁序.txt

$ ezcheck check -c sha256sum.txt
滕王阁序.txt: SHA256 OK
image.jpg: SHA256 OK
image.jpg: MD2 FAILED Current Hash: 10329710371ab70392948fcef544f728
image.jpg: MD4 FAILED Current Hash: bebc102992450c68e5543383889e27c9
image.jpg: MD5 OK
滕王阁序.txt: MD5 FAILED Current Hash: 07c4e6a2c2db5f2d3a8998a3dba84a96
滕王阁序.txt: MD4 OK
```

## License
Expand Down
84 changes: 84 additions & 0 deletions benchmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# /usr/bin/env python3
# A simple scrip to benchmark
import subprocess
import time
import os
import platform
from datetime import datetime

def measure_command_time(command):
start_time = time.time()
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
end_time = time.time()
elapsed_time = end_time - start_time
# print(f"Command Output:\n{result.stdout.decode()}")
if result.stderr:
return ("Error", f"{command} Error:\n{result.stderr.decode()}")

return ("Ok", round(elapsed_time, 4))

# Bytes -> MB
def file_size_mb(file_path):
return round(os.stat(file_path).st_size / (1024 * 1024), 4)

# Speed
def calculate_speed(file_size_MB, time_Second):
if time_Second == "Error":
return "Error"
else:
return round(file_size_MB / time_Second, 4)

def get_git_commit_hash():
try:
result = subprocess.run(
['git', 'rev-parse', '--short', 'HEAD'],
capture_output=True,
text=True,
check=True
)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
print("Error running git command:", e)
return None

if __name__ == "__main__":
file_to_test = "tests/image.jpg"
commands = {
"sha256sum": "sha256sum " + file_to_test,
"ezcheck(ring)": " target/release/ezcheck calculate sha256 -f " + file_to_test
# "ezcheck(hashes)": " target/release/ezcheck calculate sha256 -f win98.iso"
}

file_size_MB = file_size_mb(file_to_test)
git_hash = get_git_commit_hash()

# It runs slowly at the first time after being compiled.
measure_command_time("target/release/ezcheck -V")

results = []
for name, command in commands.items():
r = measure_command_time(command)
if r[0] == 'Ok':
results.append([name, r[1]])
else:
print(r[1])
results.append([name, "Error"])

sorted_results = sorted(results, key=lambda x: (x[1] == 'Error', x[1]))


print("+{:-^53}+".format("BENCHMARK-RESULTS"))
print("| Test file: {: <40}|".format(file_to_test))
print("| File size: {: <40}|".format(str(file_size_MB) + " MB"))
print("| Git hash: {: <40}|".format(git_hash))
print("+-----------------+-----------------+-----------------+")
print("|{: ^17}|{: ^17}|{: ^17}|".format("Command", "Speed(MB/s)", "Time(s)"))
print("+-----------------+-----------------+-----------------+")

for r in sorted_results:
print("|{: ^17}|{: ^17}|{: ^17}|".format(r[0], calculate_speed(file_size_MB, r[1]), r[1]))

print("+-----------------+-----------------+-----------------+")
print()
print("Platform version: " + platform.version())
print("Run time: " + datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
Loading

0 comments on commit 1fb6264

Please sign in to comment.