crypto¶
In [ ]:
open rust
open rust_operators
In [ ]:
//// test
open testing
open file_system_operators
fsharp¶
sha256¶
In [ ]:
nominal sha256 = $'System.Security.Cryptography.SHA256'
inl sha256 () : sha256 =
$'`sha256.Create' ()
sha256_compute_hash¶
In [ ]:
inl sha256_compute_hash (x : sha256) (data : a i32 u8) : a i32 u8 =
data |> $'!x.ComputeHash'
rust¶
get_file_hash'¶
In [ ]:
inl get_file_hash' (path : string) : result string string =
inl path = path |> file_system.normalize_path
inl exit_code, result =
runtime.execution_options fun x => { x with
command = $'$"pwsh -c \\\"(Get-FileHash \'{!path}\' -Algorithm SHA256).Hash\\\""'
}
|> runtime.execute_with_options
if exit_code = 0
then result |> sm'.to_lower |> Ok
else result |> Error
In [ ]:
//// test
inl file_name = "test.txt"
inl text = "\n"
inl temp_dir, disposable =
(file_name, text)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
disposable |> use |> ignore
inl path = temp_dir </> file_name
text |> file_system.write_all_text_async path |> async.run_synchronously
path
|> get_file_hash'
|> resultm.get
|> _assert_eq "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"
00:00:00 d #1 runtime.execute_with_options_async / { file_name = pwsh; arguments = US2_0 "-c "(Get-FileHash '/tmp/!create_temp_path_/dotnet-repl/9ca8b18d-ee77-4684-ad12-21e1354945fc/test.txt' -Algorithm SHA256).Hash""; options = { command = pwsh -c "(Get-FileHash '/tmp/!create_temp_path_/dotnet-repl/9ca8b18d-ee77-4684-ad12-21e1354945fc/test.txt' -Algorithm SHA256).Hash"; cancellation_token = None; environment_variables = [||]; on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:00 v #2 > 01BA4719C80B6FE911B091A7C05124B64EEECE964E09C058EF8F9805DACA546B 00:00:00 d #3 runtime.execute_with_options_async / { exit_code = 0; output_length = 64 } __assert_eq / actual: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b" / expected: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"
In [ ]:
//// test
///! rust -d chrono encoding_rs encoding_rs_io regex sha2
inl file_name = "test.txt"
inl text = "\n"
inl temp_dir, disposable =
(file_name, text)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
inl path = temp_dir </> file_name
text |> file_system.write_all_text path
path
|> get_file_hash'
|> resultm.get
|> _assert_eq "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"
disposable |> use |> ignore
00:00:00 v #1 file_system.create_dir / { dir = /tmp/!create_temp_path_/spiral_builder_936ccc021ca211f39fcdfec2c91648cb5769e52a3bca56f1eb93b32befdf6c60/ba0aa16a-6c5a-be3f-b526-70110c680e36 } 00:00:00 d #2 runtime.execute_with_options / { file_name = pwsh; arguments = ["-c", "(Get-FileHash '/tmp/!create_temp_path_/spiral_builder_936ccc021ca211f39fcdfec2c91648cb5769e52a3bca56f1eb93b32befdf6c60/ba0aa16a-6c5a-be3f-b526-70110c680e36/test.txt' -Algorithm SHA256).Hash"]; options = { command = pwsh -c "(Get-FileHash '/tmp/!create_temp_path_/spiral_builder_936ccc021ca211f39fcdfec2c91648cb5769e52a3bca56f1eb93b32befdf6c60/ba0aa16a-6c5a-be3f-b526-70110c680e36/test.txt' -Algorithm SHA256).Hash"; cancellation_token = None; environment_variables = Array(MutCell([])); on_line = None; stdin = None; trace = true; working_directory = None } } 00:00:00 v #3 > 01BA4719C80B6FE911B091A7C05124B64EEECE964E09C058EF8F9805DACA546B 00:00:00 v #4 runtime.execute_with_options / result / { exit_code = 0; std_trace_length = 64 } __assert_eq / actual: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b" / expected: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"
sha256'¶
In [ ]:
nominal sha256' =
`(
backend_switch `(()) `({}) {
Fsharp =
(fun () =>
global "#if FABLE_COMPILER\n[<Fable.Core.Erase; Fable.Core.Emit(\"sha2::Sha256\")>]\n#endif\ntype sha2_Sha256 = class end"
) : () -> ()
}
$'' : $'sha2_Sha256'
)
new_sha256¶
In [ ]:
inl new_sha256 () : sha256' =
!\($'"let result : sha2::Sha256 = sha2::Digest::new()"')
!\($'"result"')
hasher_update¶
In [ ]:
inl hasher_update forall el dim. (slice : rust.ref (am'.slice' el dim)) (hasher : sha256') : () =
!\($'"sha2::Digest::update(&mut !hasher, !slice)"')
hasher_finalize¶
In [ ]:
inl hasher_finalize (hasher : sha256') : rust.ref (am'.slice u8) =
!\($'"&sha2::Digest::finalize(!hasher)"')
hash_read¶
In [ ]:
inl hash_read data : resultm.result' string stream.io_error =
inl reader = data |> stream.new_buf_reader
(!\($'"true; let mut !reader = !reader"') : bool) |> ignore
inl hasher = new_sha256 ()
(!\($'"true; let mut !hasher = !hasher"') : bool) |> ignore
real
inl size = 1024
inl zero = convert `i32 `unativeint 0
inl buffer = am'.new_slice `u8 `@size 0u8
rust.loop 2 fun () =>
inl count = stream.buf_reader_read `u8 `@size buffer reader
inl count = resultm.unwrap' `unativeint `(stream.io_error) count
if (=.) `unativeint count zero then rust.break ()
hasher_update `u8 `@size
(
am'.slice_range `u8 `@size
(am'.Start `unativeint zero)
(am'.End `unativeint ((fun _ => count) : (() -> unativeint) -> unativeint))
buffer
)
hasher
hasher
|> hasher_finalize
|> am'.slice_to_vec
|> am'.vec_map (sm'.format_hex' >> sm'.from_std_string)
|> am'.from_vec
|> fun x => x : _ i32 _
|> seq.of_array'
|> sm'.concat (join "")
|> Ok
|> resultm.box
get_file_hash¶
In [ ]:
inl get_file_hash (path : string) =
inl path = path |> file_system.normalize_path
inl file = path |> file_system.file_open |> resultm.unwrap'
inl reader = file |> stream.new_buf_reader
reader
|> hash_read
In [ ]:
//// test
///! rust -d chrono regex sha2
inl file_name = join "test.txt"
inl text = "\n"
inl temp_dir, disposable =
(file_name, text)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
inl path = temp_dir </> file_name
text |> file_system.write_all_text path
path
|> get_file_hash
|> resultm.unwrap'
|> _assert_eq "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"
disposable |> use |> ignore
00:00:00 v #1 file_system.create_dir / { dir = /tmp/!create_temp_path_/spiral_builder_10d92c676a0f1751b08d1070ca7afc158a9c159f621443c100dd84093b70d71e/ba0aa16a-6c5a-be3f-b526-70110c680e36 }
__assert_eq / actual: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b" / expected: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"
In [ ]:
//// test
///! rust -d chrono regex sha2
inl file_name = join "test.txt"
inl text = ""
inl temp_dir, disposable =
(file_name, text)
|> sm'.format_debug
|> crypto.hash_text
|> file_system.create_temp_dir'
inl path = temp_dir </> file_name
text |> file_system.write_all_text path
path
|> get_file_hash
|> resultm.unwrap'
|> _assert_eq "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
disposable |> use |> ignore
00:00:00 v #1 file_system.create_dir / { dir = /tmp/!create_temp_path_/spiral_builder_964d613a38936bb336d0e844bc9f2182d53d4fc238886185804f65e25ce54b27/c0e26dac-4cb1-4b09-be07-ff616700f056 }
__assert_eq / actual: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" / expected: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
typescript¶
create_hash¶
In [ ]:
inl create_hash (x : string) : any =
open typescript_operators
global "type ICryptoCreateHash = abstract createHash: x: string -> obj"
inl crypto : $'ICryptoCreateHash' = typescript.import_all "crypto"
!\\(x, $'"!crypto.createHash($0)"')
hash_update¶
In [ ]:
inl hash_update (s : string) (x : any) : any =
open typescript_operators
!\\((x, s), $'"$0.update($1, \'utf8\')"')
hash_digest¶
In [ ]:
inl hash_digest (s : string) (x : any) : string =
open typescript_operators
!\\((x, s), $'"$0.digest($1)"')
python¶
py_sha256¶
In [ ]:
nominal py_sha256 = any
hashlib_sha256¶
In [ ]:
inl hashlib_sha256 () : py_sha256 =
backend_switch {
Fsharp = fun () =>
open python_operators
global "type IHashlibSha256 = abstract sha256: x: unit -> obj"
inl hashlib : $'IHashlibSha256' = python.import_all "hashlib"
!\($'"!hashlib.sha256()"') : py_sha256
Python = fun () =>
global "import hashlib"
$'hashlib.sha256()' : py_sha256
}
sha256_update¶
In [ ]:
inl sha256_update (x : string) (sha256 : py_sha256) : py_sha256 =
backend_switch {
Fsharp = fun () =>
open python_operators
!\\(x, $'"!sha256.update($0)"') : ()
Python = fun () =>
$'!sha256.update(!x)' : ()
}
sha256
sha256_hexdigest¶
In [ ]:
inl sha256_hexdigest (sha256 : py_sha256) : string =
backend_switch {
Fsharp = fun () =>
open python_operators
!\($'"!sha256.hexdigest()"') : string
Python = fun () =>
$'!sha256.hexdigest()' : string
}
crypto¶
hash_text¶
In [ ]:
let hash_text (~input : string) =
run_target function
| Fsharp (Native) => fun () =>
inl sha256 = sha256 () |> use
input
|> sm'.utf8_get_bytes
|> sha256_compute_hash sha256
|> am.map (sm'.byte_to_string "x2")
|> seq.of_array'
|> sm'.concat (join "")
| TypeScript (Native) => fun () =>
create_hash "sha256"
|> hash_update input
|> hash_digest "hex"
| Rust (Native) => fun () =>
input
|> sm'.utf8_get_bytes
|> fun (a x) => x
|> am'.to_vec
|> stream.new_cursor
|> hash_read
|> resultm.unwrap'
| Python (Native) | Cuda (Native) => fun () =>
hashlib_sha256 ()
|> sha256_update (input |> sm'.encode_utf8)
|> sha256_hexdigest
| _ => fun () => null ()
In [ ]:
//// test
///! fsharp
///! cuda
///! rust -d sha2
///! typescript
///! python
"\n"
|> hash_text
|> _assert_eq "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"
""
|> hash_text
|> _assert_eq "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
.py output (Cuda): __assert_eq / actual: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b / expected: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b __assert_eq / actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 / expected: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 .rs output (rust -d sha2): __assert_eq / actual: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b" / expected: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b" __assert_eq / actual: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" / expected: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" .ts output: __assert_eq / actual: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b / expected: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b __assert_eq / actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 / expected: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 .py output: __assert_eq / actual: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b / expected: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b __assert_eq / actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 / expected: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
.fsx output: __assert_eq / actual: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b" / expected: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b" __assert_eq / actual: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" / expected: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
hash_to_port¶
In [ ]:
inl hash_to_port (text : string) : u16 =
inl first_letter_code = text |> sm'.index 0i32 |> sm'.convert_to_utf32
inl hash_part = text |> sm'.slice 0i32 7
inl combined_value = convert_i32_base 16 hash_part + first_letter_code |> u16
trace Verbose
fun () => "crypto.hash_to_port"
fun () => { first_letter_code hash_part combined_value }
combined_value % 48128 + 1024
In [ ]:
//// test
///! fsharp
///! cuda
///! rust -d sha2
///! typescript
///! python
"\n"
|> hash_text
|> hash_to_port
|> _assert_eq 19273
.py output (Cuda): 00:00:00 v #1 crypto.hash_to_port / { first_letter_code = 48; hash_part = 01ba4719; combined_value = 18249 } __assert_eq / actual: 19273 / expected: 19273 .rs output (rust -d sha2): 00:00:00 v #1 crypto.hash_to_port / { first_letter_code = 48; hash_part = 01ba4719; combined_value = 18249 } __assert_eq / actual: 19273 / expected: 19273 .ts output: 00:00:00 v #1 crypto.hash_to_port / { first_letter_code = 48; hash_part = 01ba4719; combined_value = 18249 } __assert_eq / actual: 19273 / expected: 19273 .py output: 00:00:00 v #1 crypto.hash_to_port / { first_letter_code = 48; hash_part = 01ba4719; combined_value = 18249 } __assert_eq / actual: 19273 / expected: 19273
.fsx output:
00:00:00 v #1 crypto.hash_to_port / { first_letter_code = 48; hash_part = 01ba4719; combined_value = 18249 }
__assert_eq / actual: 19273us / expected: 19273us
main¶
In [ ]:
inl main () =
$'let hash_text x = !hash_text x' : ()
$'let hash_to_port x = !hash_to_port x' : ()