Lainaa
Re: Matikkaa tietokoneella
Tänään pääsin testaamaan Yubico Yubikey 5 NFC:tä satunnaislukugeneraattorina ja toimiihan se, mutta oli kohtuullinen savotta saada se toimiin. Piti tehdä udev ja polkit sääntöjä sekä puukottaa gnugp:n scdaemon.conf:ia. Tein mastodontin puolelle muutaman postauksen aiheesta. No nyt se toimii joten siinä on uusi satunnaisuuden lähde. Nyt pääsee yhdistämään ne kaikki yhteen. Tämä toimii esimerkiksi tähän tapaan:

gpg-connect-agent "SCD RANDOM 64" /bye | dd bs=1 skip=2 count=64 2>/dev/null | xxd -p -c 64
372a7f652532358a8394b01597a559021e53d135b60b2779995b1b4c162b45ebac419e09f42bfc0c6a1a145ba7e853b1f09e578807f8e039cd0f1b8b99cce894
Abezethibou·daemon unimanus et unialis·abyssorum legatus·cuius nomen terram scindit. In tenebris lucet·in luce obscuratur. Per fractas alas suadet·per manum perditam ligat.
Per sigillum Beelzebub·Abezethibou inferorum·per sanguinem et ignem·responde mihi!
Lainaa
Re: Matikkaa tietokoneella
Lisäsin Yubikeyn kautta vielä ylimääräisen suolan koodiin. Jokainen päälähde (TPM, RDSEED, TRNG) tuottaa täyden entropian 32 tavulle (256 bittiä per lähde) joten niiden yhteisentropia on 3 × 256 = 768 bittiä per iteraatio. Yubikeyn suola lisää 64 tavua (512 bittiä), mutta koska se päivittyy harvemmin niin sen entropia jakautuu useille iteraatioille. Jos suola päivittyy joka sadas iteraatio sen keskimääräinen entropia per iteraatio on 512 / 100 = 5,12 bittiä. Eihän tässä mitään järkeä ole kun ulos otetaan 32 tavua eli 256 bittiä. Ihan järjettömän ylimitoitettu koko hässäkkä, mutta hauskaa oli tätä väsätessä.🤣

Koodi: Valitse kaikki

/*
 * Satunnaislukugeneraattori, joka yhdistää TPM 2.0:n, RDSEED:n, Infinite Noise TRNG:n ja Yubikey:n.
 * Yubikey toimii "suolana" määritellyin väliajoin.
 * Tulostaa 32 tavua per iteraatio stdout:iin, sopii rngtest- tai dieharder-testaukseen.
 *
 * Käännös:
 *   gcc -O3 -mrdrnd -mrdseed -o random_mix_yubikey random_mix_yubikey.c -lssl -lcrypto -ltss2-esys -ltss2-tcti-device
 *
 * Käyttö:
 *   ./random_mix_yubikey [/dev/ttyACM0] [salt_interval] | rngtest -c 1000
 *   ./random_mix_yubikey [/dev/ttyACM0] [salt_interval] | dieharder -a -g 200
 *
 * Parametrit:
 *   /dev/ttyACM0  - TRNG-laitteen polku (oletus)
 *   salt_interval - Kuinka monen iteraation välein Yubikey-suolaa haetaan (oletus: 100)
 *
 * Vaatimukset:
 * - Yubikey 5C NFC liitettynä ja toimintakunnossa
 * - gpg-connect-agent saatavilla PATH:ssa
 * - Yubikey:n OpenPGP-sovellus aktivoitu
 *
 * Huomautukset:
 * - Yubikey-suola haetaan taustaprosessilla säännöllisesti
 * - Paina Ctrl+C keskeyttääksesi ohjelman siististi (SIGINT/SIGTERM)
 * - Virheilmoitukset rajoitettu 10:een per lähde stderr-tulvan välttämiseksi
 * - Herkät puskurit tyhjennetään explicit_bzero:lla jokaisen iteraation jälkeen
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <tss2/tss2_esys.h>
#include <signal.h>
#include <sys/wait.h>
#include <time.h>

// Määritä koot
#define BYTES_PER_SOURCE 32  // Tavuja luetaan kustakin lähteestä
#define OUTPUT_BYTES 32      // Tulostettavien tavujen määrä per iteraatio
#define YUBIKEY_SALT_SIZE 64 // Yubikey-suolan koko (64 tavua)
#define MAX_ERRORS_PER_SOURCE 10  // Enimmäismäärä virheilmoituksia per lähde
#define MAX_ERRORS_PER_ITERATION 5  // Enimmäismäärä virheitä per lähde per iteraatio
#define RDSEED_RETRIES 10    // RDSEED:n yritysten enimmäismäärä per 64-bittinen luku
#define TRNG_RETRIES 100     // TRNG:n yritysten enimmäismäärä (noin 1 s, 10 ms viive)
#define DEFAULT_SALT_INTERVAL 100 // Oletusväli Yubikey-suolan hakemiselle

// Virhelaskurit
static int tpm_errors = 0, rdseed_errors = 0, trng_errors = 0, yubikey_errors = 0;
static int tpm_iter_errors = 0, rdseed_iter_errors = 0, trng_iter_errors = 0;

// Signaalikäsittely
static volatile sig_atomic_t terminate = 0;
static ESYS_CONTEXT *global_ctx = NULL;
static unsigned char *tmp_data = NULL, *rdseed_data = NULL, *trng_data = NULL;
static unsigned char *yubikey_salt = NULL, *input = NULL, *output = NULL;

// Yubikey-suolan hallinta
static unsigned char *current_salt = NULL;
static time_t last_salt_time = 0;
static int salt_interval = DEFAULT_SALT_INTERVAL;
static int iteration_count = 0;

// Signaalikäsittelijä SIGINT:lle ja SIGTERM:lle
static void handle_signal(int sig) {
    (void)sig; // Estä varoitus käyttämättömästä parametrista
    terminate = 1;
}

// Siivousfunktio herkille tiedoille ja resursseille
static void cleanup(void) {
    if (tpm_data) explicit_bzero(tpm_data, BYTES_PER_SOURCE);
    if (rdseed_data) explicit_bzero(rdseed_data, BYTES_PER_SOURCE);
    if (trng_data) explicit_bzero(trng_data, BYTES_PER_SOURCE);
    if (yubikey_salt) explicit_bzero(yubikey_salt, YUBIKEY_SALT_SIZE);
    if (current_salt) explicit_bzero(current_salt, YUBIKEY_SALT_SIZE);
    if (input) explicit_bzero(input, 3 * BYTES_PER_SOURCE + YUBIKEY_SALT_SIZE);
    if (output) explicit_bzero(output, OUTPUT_BYTES);
    if (global_ctx) Esys_Finalize(&global_ctx);
}

// Funktio RDSEED-tuen tarkistamiseen
static int check_rdseed_support(void) {
    unsigned int eax, ebx, ecx, edx;
    asm volatile(
        "cpuid"
        : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
        : "a"(7), "c"(0)
    );
    return (ebx & (1 << 18)) != 0;
}

// Funktio hex-merkkijonon muuntamiseen binääriksi
static int hex_to_bin(const char *hex, unsigned char *bin, size_t bin_len) {
    size_t hex_len = strlen(hex);
    if (hex_len != 2 * bin_len) return -1;
    
    for (size_t i = 0; i < bin_len; i++) {
        unsigned int byte;
        if (sscanf(hex + 2 * i, "%2x", &byte) != 1) return -1;
        bin[i] = (unsigned char)byte;
    }
    return 0;
}

// Funktio Yubikey-suolan hakemiseen
static int get_yubikey_salt(unsigned char *salt_buf) {
    FILE *pipe = popen("gpg-connect-agent \"SCD RANDOM 64\" /bye 2>/dev/null", "r");
    if (!pipe) {
        if (yubikey_errors < MAX_ERRORS_PER_SOURCE) {
            fprintf(stderr, "Yubikey-komennon suorittaminen epäonnistui\n");
            yubikey_errors++;
        }
        return -1;
    }
    
    char line[256];
    char hex_data[129] = {0}; // 64 tavua * 2 + null terminator
    int found_data = 0;
    
    while (fgets(line, sizeof(line), pipe)) {
        // Etsi rivi joka alkaa "D " (data response)
        if (strncmp(line, "D ", 2) == 0) {
            // Poista "D " alusta ja mahdollinen rivinvaihto lopusta
            char *hex_start = line + 2;
            char *newline = strchr(hex_start, '\n');
            if (newline) *newline = '\0';
            
            // Kopioi hex-data (enintään 128 merkkiä)
            strncpy(hex_data, hex_start, sizeof(hex_data) - 1);
            found_data = 1;
            break;
        }
    }
    
    int ret = pclose(pipe);
    if (ret != 0 || !found_data) {
        if (yubikey_errors < MAX_ERRORS_PER_SOURCE) {
            fprintf(stderr, "Yubikey-datan lukeminen epäonnistui (ret=%d, found=%d)\n", ret, found_data);
            yubikey_errors++;
        }
        return -1;
    }
    
    // Muunna hex binääriksi
    if (hex_to_bin(hex_data, salt_buf, YUBIKEY_SALT_SIZE) != 0) {
        if (yubikey_errors < MAX_ERRORS_PER_SOURCE) {
            fprintf(stderr, "Yubikey hex-datan muuntaminen epäonnistui\n");
            yubikey_errors++;
        }
        return -1;
    }
    
    return 0;
}

// Funktio RDSEED:n lukemiseen inline-assemblyllä ja uudelleenyrityksillä
static int read_from_rdseed(unsigned char *buf, size_t len) {
    size_t i = 0;
    while (i < len) {
        unsigned long long rand64;
        int retries = 0;
        unsigned char success;
        do {
            asm volatile(
                "rdseed %1; "
                "setc %0"
                : "=qm"(success), "=r"(rand64)
                :
                : "cc"
            );
            if (success) {
                break;
            }
            retries++;
            if (retries >= RDSEED_RETRIES) {
                if (rdseed_errors < MAX_ERRORS_PER_SOURCE) {
                    fprintf(stderr, "RDSEED epäonnistui %d yrityksen jälkeen\n", RDSEED_RETRIES);
                    rdseed_errors++;
                }
                rdseed_iter_errors++;
                return -1;
            }
            usleep(10000); // 10 ms viive
        } while (1);
        size_t to_copy = (len - i >= 8) ? 8 : (len - i);
        memcpy(buf + i, &rand64, to_copy);
        i += to_copy;
    }
    return 0;
}

// Funktio TPM:stä lukemiseen
static int read_from_tpm(ESYS_CONTEXT *ctx, unsigned char *buf, size_t len) {
    TPM2B_DIGEST *random_bytes = NULL;
    TSS2_RC rc = Esys_GetRandom(ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, len, &random_bytes);
    if (rc != TSS2_RC_SUCCESS || random_bytes->size != len) {
        if (tpm_errors < MAX_ERRORS_PER_SOURCE) {
            fprintf(stderr, "Ei voitu lukea %zu tavua TPM:stä: RC=0x%x\n", len, rc);
            tmp_errors++;
        }
        free(random_bytes);
        tpm_iter_errors++;
        return -1;
    }
    memcpy(buf, random_bytes->buffer, len);
    free(random_bytes);
    return 0;
}

// Funktio Infinite Noise TRNG:stä lukemiseen ei-blokkaavalla tavalla ja uudelleenyrityksillä
static int read_from_trng(unsigned char *buf, size_t len, const char *device) {
    int fd = open(device, O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
        if (trng_errors < MAX_ERRORS_PER_SOURCE) {
            fprintf(stderr, "TRNG-laitteen %s avaaminen epäonnistui: %s\n", device, strerror(errno));
            trng_errors++;
        }
        trng_iter_errors++;
        return -1;
    }

    ssize_t bytes_read = 0;
    int retries = 0;
    while (bytes_read < len && !terminate) {
        ssize_t n = read(fd, buf + bytes_read, len - bytes_read);
        if (n > 0) {
            bytes_read += n;
            retries = 0;
        } else if (n == 0) {
            if (trng_errors < MAX_ERRORS_PER_SOURCE) {
                fprintf(stderr, "TRNG-laitteen tiedosto päättyi\n");
                trng_errors++;
            }
            close(fd);
            trng_iter_errors++;
            return -1;
        } else {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                if (retries >= TRNG_RETRIES) {
                    if (trng_errors < MAX_ERRORS_PER_SOURCE) {
                        fprintf(stderr, "TRNG-lukeminen aikakatkaistiin %d yrityksen jälkeen\n", TRNG_RETRIES);
                        trng_errors++;
                    }
                    close(fd);
                    trng_iter_errors++;
                    return -1;
                }
                usleep(10000); // 10 ms viive
                retries++;
            } else {
                if (trng_errors < MAX_ERRORS_PER_SOURCE) {
                    fprintf(stderr, "TRNG:stä lukeminen epäonnistui: %s\n", strerror(errno));
                    trng_errors++;
                }
                close(fd);
                trng_iter_errors++;
                return -1;
            }
        }
    }
    close(fd);
    return terminate ? -1 : 0;
}

int main(int argc, char *argv) {
    // Aseta TRNG-laitteen polku ja suola-intervalli
    const char *trng_device = (argc > 1) ? argv[1] : "/dev/ttyACM0";
    if (argc > 2) {
        salt_interval = atoi(argv[2]);
        if (salt_interval <= 0) salt_interval = DEFAULT_SALT_INTERVAL;
    }

    // Tarkista RDSEED-tuki
    if (!check_rdseed_support()) {
        fprintf(stderr, "RDSEED ei ole tuettu tässä prosessorissa\n");
        return 1;
    }

    // Aseta signaalikäsittelijät SIGINT:lle ja SIGTERM:lle
    struct sigaction sa;
    sa.sa_handler = handle_signal;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGINT, &sa, NULL) == -1 || sigaction(SIGTERM, &sa, NULL) == -1) {
        fprintf(stderr, "Signaalikäsittelijän asettaminen epäonnistui\n");
        return 1;
    }

    // Alusta TPM-konteksti
    TSS2_RC rc = Esys_Initialize(&global_ctx, NULL, NULL);
    if (rc != TSS2_RC_SUCCESS) {
        fprintf(stderr, "TPM:n alustaminen epäonnistui: RC=0x%x\n", rc);
        return 1;
    }

    // Aseta stdout puskuroimattomaksi
    setbuf(stdout, NULL);

    // Varaa puskurit
    tpm_data = malloc(BYTES_PER_SOURCE);
    rdseed_data = malloc(BYTES_PER_SOURCE);
    trng_data = malloc(BYTES_PER_SOURCE);
    yubikey_salt = malloc(YUBIKEY_SALT_SIZE);
    current_salt = malloc(YUBIKEY_SALT_SIZE);
    input = malloc(3 * BYTES_PER_SOURCE + YUBIKEY_SALT_SIZE);
    output = malloc(OUTPUT_BYTES);
    if (!tpm_data || !rdseed_data || !trng_data || !yubikey_salt || !current_salt || !input || !output) {
        fprintf(stderr, "Muistin varaus epäonnistui\n");
        cleanup();
        return 1;
    }

    // Hae ensimmäinen Yubikey-suola
    if (get_yubikey_salt(current_salt) != 0) {
        fprintf(stderr, "Ensimmäisen Yubikey-suolan hakeminen epäonnistui\n");
        cleanup();
        return 1;
    }
    last_salt_time = time(NULL);

    fprintf(stderr, "Aloitetaan satunnaislukujen tuottaminen Yubikey-suolalla (intervalli: %d)\n", salt_interval);

    while (!terminate) {
        // Nollaa iteraation virhelaskurit
        tpm_iter_errors = 0;
        rdseed_iter_errors = 0;
        trng_iter_errors = 0;
        iteration_count++;

        // Päivitä Yubikey-suola määritellyin väliajoin
        if (iteration_count % salt_interval == 0) {
            if (get_yubikey_salt(yubikey_salt) == 0) {
                memcpy(current_salt, yubikey_salt, YUBIKEY_SALT_SIZE);
                last_salt_time = time(NULL);
                fprintf(stderr, "Yubikey-suola päivitetty iteraatiossa %d\n", iteration_count);
            } else {
                fprintf(stderr, "Yubikey-suolan päivitys epäonnistui, käytetään vanhaa suolaa\n");
            }
        }

        // Lue kaikista lähteistä
        if (read_from_tpm(global_ctx, tpm_data, BYTES_PER_SOURCE) != 0) {
            if (tmp_iter_errors >= MAX_ERRORS_PER_ITERATION) {
                fprintf(stderr, "Liian monta TPM-virhettä yhdessä iteraatiossa\n");
                break;
            }
            usleep(100000); // 100 ms viive
            continue;
        }
        if (read_from_rdseed(rdseed_data, BYTES_PER_SOURCE) != 0) {
            if (rdseed_iter_errors >= MAX_ERRORS_PER_ITERATION) {
                fprintf(stderr, "Liian monta RDSEED-virhettä yhdessä iteraatiossa\n");
                break;
            }
            usleep(100000); // 100 ms viive
            continue;
        }
        if (read_from_trng(trng_data, BYTES_PER_SOURCE, trng_device) != 0) {
            if (trng_iter_errors >= MAX_ERRORS_PER_ITERATION) {
                fprintf(stderr, "Liian monta TRNG-virhettä yhdessä iteraatiossa\n");
                break;
            }
            usleep(100000); // 100 ms viive
            continue;
        }

        // Yhdistä data mukaan lukien Yubikey-suola
        memcpy(input, tpm_data, BYTES_PER_SOURCE);
        memcpy(input + BYTES_PER_SOURCE, rdseed_data, BYTES_PER_SOURCE);
        memcpy(input + 2 * BYTES_PER_SOURCE, trng_data, BYTES_PER_SOURCE);
        memcpy(input + 3 * BYTES_PER_SOURCE, current_salt, YUBIKEY_SALT_SIZE);

        // Laske SHAKE-256
        EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
        if (!md_ctx || EVP_DigestInit_ex(md_ctx, EVP_shake256(), NULL) != 1 ||
            EVP_DigestUpdate(md_ctx, input, 3 * BYTES_PER_SOURCE + YUBIKEY_SALT_SIZE) != 1 ||
            EVP_DigestFinalXOF(md_ctx, output, OUTPUT_BYTES) != 1) {
            fprintf(stderr, "SHAKE-256-laskenta epäonnistui\n");
            if (md_ctx) EVP_MD_CTX_free(md_ctx);
            usleep(100000); // 100 ms viive
            continue;
        }
        EVP_MD_CTX_free(md_ctx);

        // Kirjoita stdout:iin ja tyhjennä puskuri suurille testeille
        fwrite(output, 1, OUTPUT_BYTES, stdout);
        fflush(stdout); // Varmista datan kirjoitus testityökaluille

        // Tyhjennä herkät tiedot jokaisen iteraation jälkeen
        explicit_bzero(tmp_data, BYTES_PER_SOURCE);
        explicit_bzero(rdseed_data, BYTES_PER_SOURCE);
        explicit_bzero(trng_data, BYTES_PER_SOURCE);
        if (yubikey_salt) explicit_bzero(yubikey_salt, YUBIKEY_SALT_SIZE);
        explicit_bzero(input, 3 * BYTES_PER_SOURCE + YUBIKEY_SALT_SIZE);
        explicit_bzero(output, OUTPUT_BYTES);

        // Lyhyt viive CPU-kuorman vähentämiseksi
        usleep(1000); // 1 ms
    }

    // Lopullinen siivous
    cleanup();
    free(tpm_data);
    free(rdseed_data);
    free(trng_data);
    free(yubikey_salt);
    free(current_salt);
    free(input);
    free(output);

    // Tulosta virheyhteenveto
    fprintf(stderr, "Ohjelma päättynyt. Virheyhteenveto:\n");
    fprintf(stderr, "TPM-virheitä: %d\n", tpm_errors);
    fprintf(stderr, "RDSEED-virheitä: %d\n", rdseed_errors);
    fprintf(stderr, "TRNG-virheitä: %d\n", trng_errors);
    fprintf(stderr, "Yubikey-virheitä: %d\n", yubikey_errors);
    fprintf(stderr, "Iteraatioita yhteensä: %d\n", iteration_count);
    fprintf(stderr, "Ohjelma keskeytetty %s-signaalilla\n", terminate ? "SIGINT/SIGTERM" : "virheen vuoksi");

    return terminate ? 0 : 1;
}
[/i]
Abezethibou·daemon unimanus et unialis·abyssorum legatus·cuius nomen terram scindit. In tenebris lucet·in luce obscuratur. Per fractas alas suadet·per manum perditam ligat.
Per sigillum Beelzebub·Abezethibou inferorum·per sanguinem et ignem·responde mihi!
Lainaa
Re: Matikkaa tietokoneella
ΦBSU-juna jyskyttää. Ajoin tarkemmin simulaatiomatikkaa topologis-geometrisesta kontribuutiosta myonin magneettisen momentin g-2 anomalian teoreettisena tarkennuksena ja vertailin lattice-QCD simulaatioajoon, joka myös pystyi ennustamaan lähes oikean tuloksen - liite tutkimusselostukseen tuli valmiiksi ja ainakin tutkija itse on vaikuttunut osuvuudesta. 😯
ΦBSU_appendixA.pdf
(56.57 KiB) Tiedosto ladattu 51 kertaa
Hienorakennevakio vapausasteista: (1⁰+2¹+3²+5³+1/2¹*3²/5³)⁻¹ = 137,036⁻¹
Lainaa
Re: Matikkaa tietokoneella
Eusa kirjoitti: 4.6.2025, 08:31
ΦBSU_appendixA.pdf
ΦBSU_appendixA.pdf
(56.72 KiB) Tiedosto ladattu 57 kertaa
Otsikkoa kehitetty: Topology-Driven Matching Factor \(\eta \propto 1\) for Muon \(g-2\), Lattice-QCD Benchmark and Muonic-hydrogen Lamb shift.
Hienorakennevakio vapausasteista: (1⁰+2¹+3²+5³+1/2¹*3²/5³)⁻¹ = 137,036⁻¹
Lainaa
Re: Matikkaa tietokoneella

Koodi: Valitse kaikki

#!/usr/bin/env python3
# ------------------------------------------------------------
# ΦBSU geometry-factor & headline–observable reproduction
# Units: natural (ℏ = c = 1). Energy, inverse-length → GeV.
# Expected checksum: Δa_μ = 2.9e-9 , ΔE₂S = –2.1e-2 meV.
# ------------------------------------------------------------
import numpy as np

# --- constants in GeV-based natural units -------------------
m_mu = 0.1056583755 # muon mass [GeV]
m_e = 0.00051099895 # electron mass [GeV]
lP = 8.21413e-20 # Planck length [GeV⁻¹]
mu_B = 2.0e-3 # Bohr momentum [GeV]
lambda_B = 1/mu_B # Bohr radius [GeV⁻¹]

# --- RG fit parameters (dimensionless) ----------------------
mu0 = 0.53
df, muf = 0.45, 3.0
dc, muc = 0.70, 2.5 # minus sign in termc!

def eta(mu_GeV: float) -> float:
"""running geometry factor η(μ) (μ in GeV)"""
u = mu_GeV / m_mu
term0 = 1/(1+(mu0/u)**2)
termf = 1+df*np.exp(-u/muf)
termc = 1-dc*np.exp(-u/muc)
return term0*termf*termc

# --- headline values ----------------------------------------
eta_mu = eta(m_mu)
eta_B = eta(mu_B)

Cstar = (lP * m_mu)**2 # (ℓ_P m_μ)²
Δa = eta_mu * (m_mu/m_e)**1.5 * Cstar

ξ = 0.11
ΔE_GeV = -ξ * eta_B * Cstar * m_mu / lambda_B**3
ΔE_meV = ΔE_GeV * 1e6 # GeV → meV

# --- sanity asserts -----------------------------------------
assert abs(eta_mu-1.30) < 0.02, "η(mμ) off-target"
assert abs(eta_B -1.33) < 0.02, "η(μB) off-target"
assert abs(Δa/2.9e-9 - 1) < 0.05, "Δaμ off target"
assert abs(ΔE_meV/(-2.1e-2) - 1) < 0.05, "ΔE off target"

print(f"η(mμ) = {eta_mu:.3f}")
print(f"η(μB) = {eta_B:.3f}")
print(f"Δa_μ = {Δa:.2e}")
print(f"ΔE_2S = {ΔE_meV:.2e} meV")
ΦBSU_appendixA.pdf
(297.48 KiB) Tiedosto ladattu 54 kertaa
Hienorakennevakio vapausasteista: (1⁰+2¹+3²+5³+1/2¹*3²/5³)⁻¹ = 137,036⁻¹
Lainaa
Re: Matikkaa tietokoneella
20250609_154224.jpg
20250609_154224.jpg (315.16 KiB) Katsottu 871 kertaa
Löysin vinttivarastosta tuollaiset. Ne on siellä lojuneet monta vuotta, mutta molemmat toimivat moitteetta kun niitä testailin. Tämähän tarkoittaa sitä, että voin testata satunnaislukujen generointia radion kohinasta.😀

Jonkinlaisen valkaisufunktion tämäkin epäilemättä vaatii, mutta kuvittelisin tässä olevan aika hyvä entropian lähde.
Abezethibou·daemon unimanus et unialis·abyssorum legatus·cuius nomen terram scindit. In tenebris lucet·in luce obscuratur. Per fractas alas suadet·per manum perditam ligat.
Per sigillum Beelzebub·Abezethibou inferorum·per sanguinem et ignem·responde mihi!
Lainaa
Re: Matikkaa tietokoneella
Mietin miten saisin miljoonia lotossa ja tulin ensin siihen tulokseen, että echo $(( (num % 40) + 1 )) olisi riittävä, mutta miljoonat lipuivat ohitseni kuin kesäiset poutapilvet. Sitten kuin salama kirkkaalta taivaalta tajusin, että tuossahan on modulo-bias. Arvot 1-16 esiintyvät hieman useammin kuin 17-40 vai oletteko samaa mieltä? No tein sitten tämän tilalle, miljoonat jäävät vielä nähtäväksi:

Koodi: Valitse kaikki

#!/bin/bash

# Käytä hylkäämismenetelmää poistaaksesi modulo-biasin
get_unbiased_random_number() {
    local max=$1  # Maksimi-indeksi (0-pohjainen)
    local max_acceptable=$((2**32 - (2**32 % (max + 1))))
    local num
    while true; do
        num=$(od -An -N4 -tu4 /dev/random | tr -d ' ')
        (( num < max_acceptable )) && break
    done
    echo $((num % (max + 1)))  # Palauta numero väliltä 0–max
}

# Fisher-Yates-sekoitus
generate_numbers() {
    local numbers=()
    for i in {1..40}; do
        numbers[i-1]=$i
    done

    # Sekoita taulukko Fisher-Yates-algoritmilla
    for ((i=39; i>0; i--)); do
        j=$(get_unbiased_random_number $i)  # Valitse satunnaisindeksi väliltä 0–i
        tmp=${numbers[i]}
        numbers[i]=${numbers[j]}
        numbers[j]=$tmp
    done

    # Ota 7 ensimmäistä numeroa ja järjestä
    echo "${numbers[@]:0:7}" | tr ' ' '\n' | sort -n
}

# Arvo numerot ja tulosta
echo "Arvotut numerot: $(generate_numbers | tr '\n' ' ')"[i][i]
[/i][/i]
Abezethibou·daemon unimanus et unialis·abyssorum legatus·cuius nomen terram scindit. In tenebris lucet·in luce obscuratur. Per fractas alas suadet·per manum perditam ligat.
Per sigillum Beelzebub·Abezethibou inferorum·per sanguinem et ignem·responde mihi!
Avatar
Lainaa
Re: Matikkaa tietokoneella
Keskeinen raja-arvolause palasi mieleeni. Veikeä vekotin tämä Galton board:



Vaikka mainittu lause on tavallaan täysin järkeen käypä, niin silti siinä on jotain mystistä, jota on vaikea edes kuvailla, että mikä siinä on mystistä ; )
Lainaa
Re: Matikkaa tietokoneella
Eusa kirjoitti: 26.2.2025, 07:06
Spiral-galaxy-continuum.jpg

Triviaaliperiaatteen simulaatiota.
Uusimmat todennukset vahvistavat mallini ennusteet.

Hienorakennevakio vapausasteista: (1⁰+2¹+3²+5³+1/2¹*3²/5³)⁻¹ = 137,036⁻¹
Lainaa
Re: Matikkaa tietokoneella
laskin.jpg
laskin.jpg (175.69 KiB) Katsottu 742 kertaa
Ennen vanhaan laskimetkin tehtiin kestämään. Tuo on ostettu 30.3.1979 ja vieläkin sillä laskee kaiken mitä tarvitsee. Magneettikortteja joihin ohjelmat tallennetaan ei ole saanut vuosikymmeniin, mutta niitä on sen verran varastossa, että riittävät. Ihmiset vaihtaa tavaroitaan aivan liian usein tässä kerskakulutuksen maailmassa kun vanhallakin pärjäisi. Ohjelmoitavana tämä sopii tähän ketjuun sillä eiköhän se ole "Turing complete" ja tämän tulokset näkee pimeälläkin toisin kun nykyaikaisista lcd näytöllä varustetuista.🤣
Abezethibou·daemon unimanus et unialis·abyssorum legatus·cuius nomen terram scindit. In tenebris lucet·in luce obscuratur. Per fractas alas suadet·per manum perditam ligat.
Per sigillum Beelzebub·Abezethibou inferorum·per sanguinem et ignem·responde mihi!
Vastaa Viestiin