package main import ( "log" "math" "sort" "strings" irc "github.com/fluffle/goirc/client" ) func Entropy(s string) (e float64) { n := make(map[rune]float64) for _, r := range s { n[r] += 1 / float64(len(s)) } for _, v := range n { e -= v * math.Log2(v) } return } func Flood(s string) bool { if len(s) < 4 { return false } if v := strings.Fields(s); len(v) >= 6 { return CommonWord(v) >= 2*len(v)/3 || MedianLength(v) == 1 } return Entropy(s) <= 1 } func CommonWord(v []string) int { m := make(map[string]int) for _, w := range v { m[w]++ } l := make([]int, len(m)) for _, n := range m { l = append(l, n) } sort.Sort(sort.Reverse(sort.IntSlice(l))) return l[0] } func MedianLength(v []string) int { l := make([]int, len(v)) for i, s := range v { l[i] = len(s) } sort.Sort(sort.IntSlice(l)) return l[len(l)/2] } func DetectFlood(conn *irc.Conn, line *irc.Line) { if Flood(line.Text()) { log.Println("flood", line.Nick) conn.Kick(*room, line.Nick, "flood") } }