xpad.c
Ensign
- Registriert
- Dez. 2020
- Beiträge
- 216
TomH22 schrieb:# Prime: 33
PS: Wie sicher bist Du Dir diesbezüglich?

PPS: Oops, sollte eigentlich ein Nachtrag für den anderen Beitrag sein.
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
TomH22 schrieb:# Prime: 33
Jap, das geht auch (relativ einfach) in Bash.TomH22 schrieb:Als Stichprobe:
aaaa -> 8156 aaab->63
Den Rest überlasse ich Dir
#!/bin/bash
hash_string () {
hash_val=0x11C # Offset basis: 284
prime=0x21 # Prime: 33
mask=0x1FFF # 13-bit mask (8191)
s=$1
while (( ${#s} < 4 ));
do
s="${s}a"
done
for (( i=0; i<${#s}; i++ ));
do
j=$(printf '%d' "'${s:$i:1}") # ordinal
hash_val=$((hash_val ^ j))
hash_val=$(((hash_val * prime) & mask))
done
printf "%04d\n" "$hash_val"
}
Überhaupt nicht. Deswegen habe ich ja auch einen Disclaimer benutzt:xpad.c schrieb:PS: Wie sicher bist Du Dir diesbezüglich?![]()
TomH22 schrieb:Und gerade weil es so ist, wäre mein Ansatz, etwas etabliertes zu verwenden. Ich habe jetzt erst mal nicht geprüft ob FNV-1a wirklich was taugt, aber das wäre dann der nächste Schritt.
foofoobar schrieb:Jage das durch eine fertige Hash-Funktion deiner Wahl und das Ergebnis davon modulo 10000 nehmen.
Modulo 10000 führt einen Bias ein. Man darf nur auf ganze Bits kürzen, d.h. Modulo einer Zweierpotenz.BeBur schrieb:Das wäre schon sehr kurios, wenn Teilsequenzen des Ergebnisses einen Bias hätten.
h \in [0,15]
.h
jetzt auf eine Dezimalstelle kürzen wollen mit f(h) := h mod 10
, dann hätten wir folgende Verteilung:f(h) | Urbild (d.h. mögl. Werte für h) | Häufigkeit |
0 | 0, 10 | 12,5% |
1 | 1, 11 | 12,5% |
2 | 2, 12 | 12,5% |
3 | 3, 13 | 12,5% |
4 | 4, 14 | 12,5% |
5 | 5, 15 | 12,5% |
6 | 6 | 6,25% |
7 | 7 | 6,25% |
8 | 8 | 6,25% |
9 | 9 | 6,25% |
Und genau diese Aussage ist falsch. Meine Implementierung hat keinen Bias / ist gleichverteilt.simpsonsfan schrieb:Dass ein Modulo 10000 einen Bias einführt, steht hier schon im Thread.
Marco01_809 schrieb:Stimmt, ging unter beim Überfliegen weil der Thread sich irgendwie im Kreis drehte.
Marco01_809 schrieb:SHA256 ist erstmal eine 256 Bit lange Zahl. Die kann man hexadezimal darstellen (sollte man meistens auch) aber zwischen den Anforderungen vom OP schien mir die Ausgabe mit 4 Dezimalstellen noch die festeste zu sein.
Wie oft denn noch, dass das nicht ausreicht?Piktogramm schrieb:Jeder der etwas Produktives bauen wollte würde AES, SHA draufwerfen,
Wobei bei 2**256 (115792089237316195423570985008687907853269984665640564039457584007913129639936)Piktogramm schrieb:Und an Stelle des TE wäre es deutlich sinnvoller statt zuerst Code zu schreiben mal zu formulieren, welche Probleme sich ergeben, wenn man einen Raum aus 26^4 Elementen auf eine Menge von 10.000 gleichmäßig abbilden will. Gefolgt von der Überlegung, wie diese Abbildung halbwegs zufällig erfolgt auf diese deutlich kleinere Menge erfolgen kann. Lustigerweise kommt da die korrekte Aussage zum Verhalten von Modulo wieder ins Spiel.
Tja, wenn man nur wüsste was der TO wirklich vorhat (ein Perpetuum mobile?) könnte man sicherlich helfen, aber das ist wahrscheinlich top secret.Piktogramm schrieb:[1] Das ist der Punkt wo sich über "glauben" etc. lustig gemacht wurde. Dem TE wäre anzuraten rfc2119 zu lesen und aufs Deutsche zu übertragen.
Stimmt, guter Punkt. Wobei der Bias ziemlich klein ist bei einer 256 Bit Zahl Modulo 10.000. Ich vage zu behaupten, dass man den in vielen Anwendungsfällen akzeptieren kann.Marco01_809 schrieb:die Ausgabe mit 4 Dezimalstellen noch die festeste zu sein. Und dann ist SHA256 kürzen nicht mehr trivial.
Die sind nicht kollisionsresistent und es wurde explizit kollisionsresistenz als anforderung genannt.. nicht dass das jetzt viel aussagt, ich würde raten dass die eigentlich nicht benötigt wird und etwas anderes gemeint gewesen.JoergB schrieb:
[0, 2^256-1]
auf [0,9999]
herunterzuskalieren (noch nicht vorgeschlagen oder ich habs übersehen)?x = (2^256)/10 000
Zahlen von [0, 2^256-1]
zugewiesen:use primitive_types::{U256, U512};
use sha2::{Sha256, Digest};
fn hash(input: &str, scale_limit: u16) -> u16 {
let mut hasher = Sha256::new();
hasher.update(input);
let sha256_hash = hasher.finalize();
let sha256_hash = U256::from_little_endian(sha256_hash.as_slice());
let scaled_hash = sha256_hash.full_mul(U256::from(scale_limit)) / U256::max_value();
scaled_hash.try_into().expect("result is smaller than 2^16")
}
fn hash_improved(input: &str, scale_limit_exclusive: u16) -> u16 {
let mut hasher = Sha256::new();
hasher.update(input);
let sha256_hash = hasher.finalize();
let sha256_hash = U256::from_little_endian(sha256_hash.as_slice());
let scaled_hash = sha256_hash.full_mul(U256::from(scale_limit_exclusive))
/ (U512::from(U256::max_value()) + 1);
scaled_hash.try_into().expect("result is smaller than 2^16")
}
fn main() {
let chars = b'A' ..= b'Z';
let (mut hashes, mut i_hashes) = (Vec::new(), Vec::new());
for a in chars.clone(){
for b in chars.clone(){
for c in chars.clone(){
for d in chars.clone(){
let string = [a, b, c, d];
let str = str::from_utf8(&string).expect("valid utf8");
let hash = hash(str, 10_000);
let hash_improved = hash_improved(str, 10_000);
println!("{str} -> {hash:04}");
println!("{str} -> {hash_improved:04}");
hashes.push(hash);
i_hashes.push(hash_improved);
}
}
}
}
let (min, max) = (hashes.iter().min().unwrap(), hashes.iter().max().unwrap());
let (min_i, max_i) = (i_hashes.iter().min().unwrap(), i_hashes.iter().max().unwrap());
let equal = hashes == i_hashes;
println!("equal: {equal}");
println!("min: {min}, max: {max}");
println!("min_i: {min_i}, max_i: {max_i}");
}
(2^256-1)*10000/(2^256-1)=10 000
herauskommen, daher habe ich eine zweite Variante hinzugefügt, die stattdessen (2^256-1)*10000/2^256<10 000
rechnet und dadurch ein Abrunden erzwingt....
ZZZY -> 6302
ZZZY -> 6302
ZZZZ -> 5374
ZZZZ -> 5374
equal: true
min: 0, max: 9999
min_i: 0, max_i: 9999
Braucht halt eine Sprache die mit solchen Werten (u256) rechnen kann oder entsprechende Libs.KitKat::new() schrieb:Was spricht eigentlich dagegen[0, 2^256-1]
auf[0,9999]
herunterzuskalieren (noch nicht vorgeschlagen oder ich habs übersehen)?
Jede Zahl von 0-9999 bekommtx = (2^256)/10 000
Zahlen von[0, 2^256-1]
zugewiesen:
KitKat::new() schrieb:Anscheinend kann das Rust :-)Rust:use primitive_types::{U256, U512};
Ich nerv dich morgen mit ein paar Fragen zu dem Code.
KitKat::new() schrieb:Was spricht eigentlich dagegen[0, 2^256-1]
auf[0,9999]
herunterzuskalieren (noch nicht vorgeschlagen oder ich habs übersehen)?
foofoobar schrieb:Jage das durch eine fertige Hash-Funktion deiner Wahl und das Ergebnis davon modulo 10000 nehmen.
CyborgBeta schrieb:Nein, dann sind es zwei Verfahren, anstatt eins.
$ echo "Hello, World!" | crcany -16
CRC-16/ARC: 0x32ba
CRC-16/CDMA2000: 0x5086
CRC-16/CMS: 0x85ce
CRC-16/DDS-110: 0x2d41
CRC-16/DECT-R: 0x19a6
CRC-16/DECT-X: 0x19a7
CRC-16/DNP: 0x391e
CRC-16/EN-13757: 0x060a
CRC-16/GENIBUS: 0x98f4
CRC-16/GSM: 0x319e
CRC-16/IBM-3740: 0x670b
CRC-16/IBM-SDLC: 0xde99
CRC-16/ISO-IEC-14443-3-A: 0xca1b
CRC-16/KERMIT: 0x77f3
CRC-16/LJ1200: 0xbab0
CRC-16/MAXIM-DOW: 0xcd45
CRC-16/MCRF4XX: 0x2166
CRC-16/MODBUS: 0x3311
CRC-16/NRSC-5: 0x2fac
CRC-16/OPENSAFETY-A: 0xa095
CRC-16/OPENSAFETY-B: 0x9fd5
CRC-16/PROFIBUS: 0xdf52
CRC-16/RIELLO: 0x7c34
CRC-16/SPI-FUJITSU: 0xa46b
CRC-16/T10-DIF: 0x7fbb
CRC-16/TELEDISK: 0x51ba
CRC-16/TMS37157: 0xae23
CRC-16/UMTS: 0x504e
CRC-16/USB: 0xccee
CRC-16/XMODEM: 0xce61
Gibt es einen Bias?KitKat::new() schrieb:Was spricht eigentlich dagegen[0, 2^256-1]
auf[0,9999]
herunterzuskalieren
BeBur schrieb:Das Ergebnis ist dann nicht mehr gleichverteilt, d.h. manche Inputs haben höhrere Chancen für Kollisionen als andere. Ob das ein Problem ist? Keine Ahnung
Hashfunktionen sollen im Allgmeinen auf beliebigen Input anwendbar sein, an der Stelle kommt dort eine Anforderung an Gleichverteilung von Pseudozufallswerten rein, die eben nicht pauschal mit "Der Bias ist aber kleiner 1" abgetan werden kann.CyborgBeta schrieb:Doch. Es genügt, wenn die Anzahl der Vorkommen zwischen ceil(Optimalwert)-1 und ceil(Optimalwert) liegen.
TomH22 schrieb:"Kunstfehler" [...] Dazu gehört z.B. auch Race Conditions bei parallelen Zugriffen zu ignorieren, weil "die Wahrscheinlichkeit gering ist".