1use sha2::{Digest, Sha256};
4
5pub fn random_bytes<const N: usize>() -> [u8; N] {
7 let mut out = [0u8; N];
8 getrandom::fill(&mut out).expect("the OS random number generator is available");
9 out
10}
11
12pub fn sha256_hex(data: &[u8]) -> String {
15 hex::encode(Sha256::digest(data))
16}
17
18pub fn unix_now() -> i64 {
20 std::time::SystemTime::now()
21 .duration_since(std::time::UNIX_EPOCH)
22 .expect("the clock is after 1970")
23 .as_secs() as i64
24}
25
26pub fn rfc3339(unix: i64) -> String {
29 time::OffsetDateTime::from_unix_timestamp(unix)
30 .ok()
31 .and_then(|t| t.format(&time::format_description::well_known::Rfc3339).ok())
32 .unwrap_or_default()
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38
39 #[test]
40 fn random_bytes_differ_between_calls() {
41 assert_ne!(random_bytes::<32>(), random_bytes::<32>());
42 }
43
44 #[test]
45 fn sha256_hex_matches_the_known_digest_of_abc() {
46 assert_eq!(
47 sha256_hex(b"abc"),
48 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
49 );
50 }
51
52 #[test]
53 fn rfc3339_formats_kernel_timestamps_in_utc_and_out_of_range_as_empty() {
54 assert_eq!(rfc3339(0), "1970-01-01T00:00:00Z");
55 assert_eq!(rfc3339(1_700_000_000), "2023-11-14T22:13:20Z");
56 assert_eq!(rfc3339(i64::MAX), "");
57 }
58}