Girdiyi yayan işlev


14

Aşağıdaki özelliklere sahip n-bit sayılardan n-bit sayılara bir işlev olup olmadığını bilmek istiyorum :f

  • f yönlü olmalı
  • Hem hem de oldukça hızlı hesaplanabilir olmalıdırff1
  • f , girdisiyle anlamlı bir korelasyonu olmayan bir sayı döndürmelidir.

Gerekçe şudur:

Veriler üzerinde çalışan bir program yazmak istiyorum. Verilerin bazı bilgileri, arama anahtarının bir alfabenin sembolü olduğu ikili bir arama ağacında saklanır. Zamanla alfabeye başka semboller ekliyorum. Yeni semboller sadece bir sonraki boş numarayı alır. Bu nedenle, ağaç her zaman küçük anahtarlara küçük bir önyargıya sahip olacaktır, bu da bence gerekli olması gerektiğinden daha fazla yeniden dengelenmeye neden olur.

Benim fikrim, sembol numaralarını ile ( geniş bir alana yayılacak şekilde değiştirmek . Sembol numaraları sadece bir kez gerçekleşen giriş ve çıkış sırasında önemli olduğundan, böyle bir fonksiyonun uygulanması çok pahalı olmamalıdır.f[0,2641]

Xorshift rasgele sayı üretecinin bir tekrarı hakkında düşündüm, ancak teorik olarak mümkün olsa da, onu geri almanın bir yolunu gerçekten bilmiyorum.

Böyle bir işlevi bilen var mı?
Bu iyi bir fikir mi?


1
Ben uzman değilim, ama belki de sahte bir permütasyon kullanabilirsiniz (örneğin Feistel şifresi )
Vor

Temelde bir karma işlevi hesaplıyorsanız, neden karma kullanmıyorsunuz?
vonbrand

@vonbrand Hashing geri alınamaz. Bkz. Gereksinim numarası 2.
FUZxxl

Neden tersinir olmak zorunda? Arama ile geri döndürülebilir hale getirmenin yanlışlığı nedir?
vonbrand

1
(F (x), x) tuşlarını saklayabilirsiniz.
adrianN

Yanıtlar:


6

Sen kullanabilirsiniz Fibonacci karma yani

hF(k)=k512k512 .

For almak İkili-ayrı sayılar (yaklaşık) eşit yayılmış . ölçeklendirip yuvarlayarak (aşağı) çevirerek, bu aralıktaki sayıları eşit olarak .n [ 0 , 1 ] [ 1 .. M ]k=1,,nn[0,1][1..M]

Örneğin, bunlar ölçeklendirilmiş (sol orijinal sıra, sağ sıralı):[ 0..10000 ]hF(1),,hF(200)[0..10000]

resim açıklamasını buraya girin

Bu, Knuth'un çarpma hashlaması dediği bir örnektir . For Bilgisayarınızın kelime büyüklüğü, bazı tamsayı aralarında asal ve gerekli adres sayısı, kullandığımızA w MwAwM

h(k)=M((kAw)mod1)

karma işlevi olarak. Yukarıdakiler (yeterli bir hassasiyetle hesaplayabildiğinizden emin olun). Bu, dışında başka bir irrasyonel sayı ile de da, "en eşit dağıtılmış" sayılara götüren yalnızca iki sayıdan biridir.A/w=ϕ1=512ϕ1

Donald Knuth'un Bilgisayar Programlama Sanatı , Cilt 3 (ikinci baskıda bölüm 513, sayfa 6.4) bölümünde daha fazlasını bulabilirsiniz. Özellikle elde edilen sayıların neden çift olarak farklı olduğunu (en azından ) ve yerine doğal ve kullanırsanız ters fonksiyonun nasıl hesaplanacağını bulacaksınız .nMAwϕ1


1
Etkin nasıl hesaplanır ? f1
13'te frafl

1
@frafl Umarım düzenlemem endişenizi biraz çözer. Bununla birlikte, bu hash tekniklerinin ne de verimli bir şekilde tersine çevrilemez şekilde tasarlandığı açık değildir.
Raphael

Evet, onaylayacağım, ancak kabul edilen cevap olarak tavsiye etmem.
13'te frafl

1

İçin bitlik girişler, bu fonksiyon çalışır:k

hash(n)=(nmod2k2)2k2+ndiv2k2

Bu tersine çevrilebilir, çünkü ve sıralı olmayan çiftler , burada . Çıktı ve girdinin, özellikle arasındaysa, ilişkili olabileceğine dikkat edin .hash(hash(n))=n{n,m},n<mhash(m)<hash(n){1,,2k21}

Ref: Ters çevrilebilir karma işlevi


Bu basit ve hoş görünüyor. Bunu test edeceğim.
FUZxxl

1
1. Girdiye bağlı olarak, ağır korelasyon üretebilir ( Spearman'ın için kadar ) 2. Bu 32 bit için, 64 bit için değil 3. Bunu dilden bağımsız bir şekilde yazabilir misiniz? 1ρ
13'te frafl

oldukça açık! 64 bit (0x00000000FFFFFFFF) için (32) 32 bit kaydırmalısınız. Bu fonksiyon basit, pratik ve pratikte yeterince hızlı.
Reza

1
Ama neden bitlerin permütasyonunu kullanmıyorsunuz ki bu her ile eşleşmiyor ? Yukarıda belirtildiği gibi, bu OP tarafından talep edilen korelasyon koşulunu açıkça ihlal etmektedir. x{1,,2321}232x
frafl
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.