Instantly share code, notes, and snippets.

@Merovius /entropy.go
Last active Jan 15, 2018

Embed
What would you like to do?
Generating entropy without imports in Go
// https://blog.merovius.de/2018/01/15/generating_entropy_without_imports_in_go.html
package main
import "fmt"
func main() {
fmt.Println(MapIteration())
fmt.Println(Select())
fmt.Println(RaceCondition())
fmt.Println(DataRace())
}
func MapIteration() string {
var r rand
m := make(map[uint32]bool)
for i := uint32(0); i < 100; i++ {
m[i] = true
}
for i := 0; i < 1000; i++ {
for k := range m {
r.mix(k)
break // the rest of the loop is deterministic
}
}
return hex(r.rand())
}
func Select() string {
var r rand
ch := make(chan bool)
close(ch)
for i := 0; i < 1000; i++ {
select {
case <-ch:
r.mix(1)
case <-ch:
r.mix(2)
}
}
return hex(r.rand())
}
func RaceCondition() string {
var r rand
for i := 0; i < 1000; i++ {
ch := make(chan uint32, 2)
start := make(chan bool)
go func() {
<-start
ch <- 1
}()
go func() {
<-start
ch <- 2
}()
close(start)
r.mix(<-ch)
}
return hex(r.rand())
}
func DataRace() string {
var r rand
var data *uintptr
var addr *uintptr
var i, j, k interface{}
i = (*uintptr)(nil)
j = &data
done := false
go func() {
for !done {
k = i
k = j
}
}()
for {
if p, ok := k.(*uintptr); ok && p != nil {
addr = p
done = true
break
}
}
data = new(uintptr)
r.mix(uint32(*addr))
return hex(r.rand())
}
type rand uint32
func (r *rand) mix(v uint32) {
*r = ((*r << 5) + *r) + rand(v)
}
func (r *rand) rand() uint32 {
mx := rand(int32(*r)>>31) & 0xa8888eef
*r = *r<<1 ^ mx
return uint32(*r)
}
func hex(v uint32) string {
var b []byte
for v != 0 {
if x := byte(v & 0xf); x < 10 {
b = append(b, '0'+x)
} else {
b = append(b, 'a'+x-10)
}
v >>= 4
}
return string(b)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment