Selaa lähdekoodia

A beautiful commit.

Joshua Rutschmann 8 vuotta sitten
vanhempi
commit
74e56338ba
4 muutettua tiedostoa jossa 271 lisäystä ja 5 poistoa
  1. 4
    0
      hw8/task1/Cargo.toml
  2. 116
    5
      hw8/task1/src/lib.rs
  3. 144
    0
      hw8/task1/src/main.rs
  4. 7
    0
      hw8/task1/src/unit_test.rs

+ 4
- 0
hw8/task1/Cargo.toml Näytä tiedosto

4
 authors = ["Joshua Rutschmann <joshua.rutschmann@gmx.de>"]
4
 authors = ["Joshua Rutschmann <joshua.rutschmann@gmx.de>"]
5
 
5
 
6
 [dependencies]
6
 [dependencies]
7
+sha2 = "0.7.0"
8
+clap = "2.28"
9
+time = "0.1"
10
+sys-info = "*"

+ 116
- 5
hw8/task1/src/lib.rs Näytä tiedosto

1
-#[cfg(test)]
2
-mod tests {
3
-    #[test]
4
-    fn it_works() {
5
-        assert_eq!(2 + 2, 4);
1
+extern crate sha2;
2
+#[cfg(feature = "SHA2")]
3
+use self::sha2::Sha256;
4
+
5
+
6
+pub struct Sha256;
7
+
8
+pub trait Hasher {
9
+    type Output: HashResult;
10
+    fn hash(input: &[u8]) -> Self::Output;
11
+}
12
+
13
+pub trait HashResult {
14
+    /// Get the output in hex notation.
15
+    fn hex(&self) -> String;
16
+    /// Size of the output in bytes.
17
+    fn size() -> usize;
18
+}
19
+
20
+
21
+impl Hasher for Sha256 {
22
+    type Output = [u8; 32];
23
+
24
+    fn hash(input: &[u8]) -> Self::Output {
25
+        use self::sha2::*;
26
+        let mut tmp = Sha256::new();
27
+        tmp.input(input);
28
+        let r = tmp.result().as_slice().to_vec();
29
+        [
30
+            r[0],
31
+            r[1],
32
+            r[2],
33
+            r[3],
34
+            r[4],
35
+            r[5],
36
+            r[6],
37
+            r[7],
38
+            r[8],
39
+            r[9],
40
+            r[10],
41
+            r[11],
42
+            r[12],
43
+            r[13],
44
+            r[14],
45
+            r[15],
46
+            r[16],
47
+            r[17],
48
+            r[18],
49
+            r[19],
50
+            r[20],
51
+            r[21],
52
+            r[22],
53
+            r[23],
54
+            r[24],
55
+            r[25],
56
+            r[26],
57
+            r[27],
58
+            r[28],
59
+            r[29],
60
+            r[30],
61
+            r[31],
62
+        ]
63
+    }
64
+}
65
+
66
+impl HashResult for [u8; 32] {
67
+    fn hex(&self) -> String {
68
+        const HEX: [char; 16] = [
69
+            '0',
70
+            '1',
71
+            '2',
72
+            '3',
73
+            '4',
74
+            '5',
75
+            '6',
76
+            '7',
77
+            '8',
78
+            '9',
79
+            'a',
80
+            'b',
81
+            'c',
82
+            'd',
83
+            'e',
84
+            'f',
85
+        ];
86
+        let mut tmp = String::with_capacity(32 * 2);
87
+        for byte in self.iter() {
88
+            tmp.push(HEX[*byte as usize / 16]);
89
+            tmp.push(HEX[*byte as usize % 16]);
90
+        }
91
+        tmp
92
+    }
93
+
94
+    fn size() -> usize {
95
+        32
96
+    }
97
+}
98
+
99
+
100
+pub struct Solution {
101
+    pub number: usize,
102
+    pub hash: String,
103
+}
104
+
105
+pub fn verify_product(base: usize, number: usize, difficulty: &String) -> Option<Solution> {
106
+    let sol = base * number;
107
+    let input = sol.to_string();
108
+    let bytes = input.as_bytes();
109
+
110
+    let hash = Sha256::hash(bytes).hex();
111
+
112
+    if hash.ends_with(difficulty) {
113
+        return Some(Solution{ number: number, hash: hash,});
6
     }
114
     }
115
+
116
+    None
7
 }
117
 }
118
+

+ 144
- 0
hw8/task1/src/main.rs Näytä tiedosto

1
+extern crate clap;
2
+extern crate time;
3
+extern crate task1;
4
+extern crate sys_info;
5
+
6
+use std::sync::mpsc::channel;
7
+use time::get_time;
8
+use clap::{Arg, App, SubCommand};
9
+use std::{process, thread};
10
+use task1::verify_product;
11
+use std::sync::Arc;
12
+
13
+pub fn main() {
14
+    let matches = create_app().get_matches();
15
+    let base = matches.value_of("base").unwrap_or("1");
16
+    let diff = Arc::new(matches.value_of("difficulty").unwrap_or("1").to_string());
17
+    let cpus = sys_info::cpu_num().unwrap_or(1).to_string();
18
+    let threads = matches.value_of("threads").unwrap_or(&cpus);
19
+    let mut time_measurement = false;
20
+
21
+    if diff.chars().any(|c| !c.is_digit(16)) {
22
+        println!("Difficulty is not hexadecimal.");
23
+        process::exit(1)
24
+    }
25
+
26
+    if let Some(ref sub_command) = matches.subcommand {
27
+        if sub_command.name.eq("timings") {
28
+            time_measurement = true;
29
+        }
30
+    }
31
+
32
+    if true {
33
+        println!("--------------------------------------------");
34
+        println!(
35
+            "Container:    : \"{}\"",
36
+            sys_info::hostname().unwrap_or("-".to_string())
37
+        );
38
+        println!("Physical CPUs : {}", sys_info::cpu_num().unwrap_or(0));
39
+        println!("Logical CPUs  : {}", sys_info::cpu_num().unwrap_or(0));
40
+        println!("CPU Speed     : {}", sys_info::cpu_speed().unwrap_or(0));
41
+        println!("Load Average  : {:?}", sys_info::loadavg().unwrap());
42
+        println!("Processes     : {}", sys_info::proc_total().unwrap_or(0));
43
+        println!("--------------------------------------------");
44
+    }
45
+
46
+    match (base.parse::<usize>(), threads.parse::<usize>()) {
47
+        (Ok(b), Ok(t)) => {
48
+            println!("Using base: {}", b);
49
+            println!("Using difficulty: {}", diff);
50
+            println!("Please wait...");
51
+            let start = get_time();
52
+            let max = <usize>::max_value();
53
+            let mut children = vec![];
54
+
55
+            let (tx, rx) = channel();
56
+
57
+            for i in 0..t {
58
+                let d = diff.clone();
59
+                let tx = tx.clone();
60
+
61
+                children.push(thread::spawn(move || {
62
+                    let from = max / t * i;
63
+                    let to = max / t * (i + 1);
64
+                    println!("{} - {} | Thread {} | Difficulty is: {}", from, to, i, d);
65
+
66
+                    for n in from..to {
67
+                        if let Some(x) = verify_product(b, n, &d) {
68
+                            let end = get_time();
69
+                            println!("Number: {} --> hash: {}", x.number, x.hash);
70
+                            if time_measurement {
71
+                                let diff = end - start;
72
+                                let s = diff.num_seconds();
73
+                                let ms = diff.num_milliseconds();
74
+                                let us = diff.num_microseconds().unwrap_or(ms * 1000);
75
+                                println!("(Duration {}s / {}ms / {}us)", s, ms, us);
76
+                            }
77
+                            tx.send("Finished").unwrap();
78
+                        }
79
+                    }
80
+
81
+                }));
82
+            }
83
+
84
+            match rx.recv() {
85
+                Ok(msg) => {
86
+                    println!("{}", msg);
87
+                }
88
+                Err(_) => {}
89
+            }
90
+
91
+            /*
92
+            for child in children {
93
+                let _ = child.join();
94
+            } 
95
+            */
96
+        }
97
+        (_, Err(_)) => {
98
+            println!("Number of threads is not integer.");
99
+            process::exit(1)
100
+        }
101
+        (Err(_), _) => {
102
+            println!("Base is not integer.");
103
+            process::exit(1)
104
+        }
105
+    };
106
+}
107
+
108
+fn create_app<'a, 'b>() -> App<'a, 'b> {
109
+    App::new("Hash256")
110
+        .version("1.0")
111
+        .author("Lorenz Bung & Joshua Rutschmann")
112
+        .about(
113
+            "Calculates the Hashvalue of the given base, number and difficulty.",
114
+        )
115
+        .arg(
116
+            Arg::with_name("base")
117
+                .value_name("base")
118
+                .help("The base of the hash to be calculated on.")
119
+                .takes_value(true)
120
+                .required(true),
121
+        )
122
+        .arg(
123
+            Arg::with_name("difficulty")
124
+                .value_name("difficulty")
125
+                .help("The difficulty of the calculated hash.")
126
+                .takes_value(true)
127
+                .required(true),
128
+        )
129
+        .arg(
130
+            Arg::with_name("threads")
131
+                .value_name("threads")
132
+                .help(
133
+                    "Sets the number of the threads to use (default = number of cpus)",
134
+                )
135
+                .takes_value(true)
136
+                .required(false),
137
+        )
138
+        .subcommand(
139
+            SubCommand::with_name("timings")
140
+                .about("controls timing features")
141
+                .version("1.0")
142
+                .author("Lorenz Bung & Joshua Rutschmann"),
143
+        )
144
+}

+ 7
- 0
hw8/task1/src/unit_test.rs Näytä tiedosto

1
+#[test]
2
+fn test_hash() {
3
+    assert_eq!(
4
+        Sha256::hash("test".as_bytes()).hex(),
5
+        "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
6
+    );
7
+}

Loading…
Peruuta
Tallenna