From 348db0bead25f9b39adc0bd6dbd575762194dd4b Mon Sep 17 00:00:00 2001 From: hanez Date: Mon, 29 Sep 2025 09:11:18 +0200 Subject: [PATCH] Added sha256_str to class sha256.fun + a demo and some .editorconfig update. (0.12.1) --- .editorconfig | 5 ++++ CMakeLists.txt | 2 +- examples/sha256_str_demo.fun | 37 +++++++++++++++++++++++ lib/crypt/sha256.fun | 58 ++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 examples/sha256_str_demo.fun diff --git a/.editorconfig b/.editorconfig index 477fe3c..e7b467c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -53,6 +53,11 @@ indent_style = tab ij_csv_keep_indents_on_empty_lines = true ij_csv_wrap_long_lines = false +[*.fun] +indent_style = space +indent_size = 2 +tab_width = 1 + [{*.markdown,*.md}] indent_style = space indent_size = 2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d0831f..96e1abe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(fun VERSION 0.12.0 LANGUAGES C) +project(fun VERSION 0.12.1 LANGUAGES C) set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/examples/sha256_str_demo.fun b/examples/sha256_str_demo.fun new file mode 100644 index 0000000..567448f --- /dev/null +++ b/examples/sha256_str_demo.fun @@ -0,0 +1,37 @@ +#!/usr/bin/env fun + +/* + * This file is part of the Fun programming language. + * https://hanez.org/project/fun/ + * + * Copyright 2025 Johannes Findeisen + * Licensed under the terms of the ISC license. + * https://opensource.org/license/isc-license-txt + * + * Added: 2025-09-29 + */ + +// Demo: SHA-256 of raw strings (no hex decoding) +include "lib/crypt/sha256.fun" + +sha = SHA256() + +print("=== SHA-256 demo (raw string input via sha256_str) ===") + +// "" (empty string) +print(sha.sha256_str("")) // -> e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + +// "abc" +print(sha.sha256_str("abc")) // -> 3859a4ec00dcbed7c01d4a462d18c1f4097a690a1d4d459be4e5b6f5a594ee68 + +// "616263" (the literal characters '6','1','6','2','6','3') +print(sha.sha256_str("616263")) // -> faee5966a2c104cf2287085428a183fe58c18afdc5ff261571e8e9c4796ad635 + +// "message digest" +print(sha.sha256_str("6d65737361676520646967657374")) // -> + +// "abcdefghijklmnopqrstuvwxyz" +print(sha.sha256_str("6162636465666768696a6b6c6d6e6f707172737475767778797a")) // -> + +print("=== Note ===") +print("sha256_str(\"616263\") hashes the text 616263; sha256_hex(\"616263\") hashes bytes 0x61 0x62 0x63 (abc).") diff --git a/lib/crypt/sha256.fun b/lib/crypt/sha256.fun index f297972..30d4164 100644 --- a/lib/crypt/sha256.fun +++ b/lib/crypt/sha256.fun @@ -259,3 +259,61 @@ class SHA256() bytes = this.from_hex(hexStr) digest = this.sha256_bytes(bytes) return this.bytes_to_hex(digest) + + // Convert a printable ASCII string (0x20..0x7E) to byte array + fun string_to_bytes_ascii(this, s) + str = to_string(s) + out = [] + number i = 0 + // ASCII printable ranges + P1 = " !\"#$%&'()*+,-./" // 32..47 + P2 = "0123456789" // 48..57 + P3 = ":;<=>?@" // 58..64 + P4 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // 65..90 + P5 = "[\\]^_`" // 91..96 + P6 = "abcdefghijklmnopqrstuvwxyz" // 97..122 + P7 = "{|}~" // 123..126 + while true + ch = substr(str, i, 1) + if (typeof(ch) != "String" || ch == "") + break + number code = -1 + idx = find(P1, ch) + if (idx >= 0) + code = 32 + idx + else + idx = find(P2, ch) + if (idx >= 0) + code = 48 + idx + else + idx = find(P3, ch) + if (idx >= 0) + code = 58 + idx + else + idx = find(P4, ch) + if (idx >= 0) + code = 65 + idx + else + idx = find(P5, ch) + if (idx >= 0) + code = 91 + idx + else + idx = find(P6, ch) + if (idx >= 0) + code = 97 + idx + else + idx = find(P7, ch) + if (idx >= 0) + code = 123 + idx + else + // non-printable -> 0 + code = 0 + push(out, code) + i = i + 1 + return out + + // Hash raw string bytes (printable ASCII). Example: sha512_str("616263") -> ee2109... + fun sha256_str(this, str) + bytes = this.string_to_bytes_ascii(str) + digest = this.sha256_bytes(bytes) + return this.bytes_to_hex(digest)