pkg: added random string, peer

This commit is contained in:
Leo Balduf 2016-04-02 15:40:47 -04:00
parent e9c481e500
commit 986aa41d65
4 changed files with 173 additions and 0 deletions

74
pkg/random/peer.go Normal file
View file

@ -0,0 +1,74 @@
// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package random
import (
"math/rand"
"net"
"github.com/chihaya/chihaya"
)
// Peer generates a random chihaya.Peer.
//
// prefix is the prefix to use for the peer ID. If len(prefix) > 20, it will be
// truncated to 20 characters. If len(prefix) < 20, it will be padded with an
// alphanumeric random string to have 20 characters.
//
// v6 indicates whether an IPv6 address should be generated.
// Regardless of the length of the generated IP address, its bytes will have
// values in [1,254].
//
// minPort and maxPort describe the range for the randomly generated port, where
// minPort <= port < maxPort.
// minPort and maxPort will be checked and altered so that
// 1 <= minPort <= maxPort <= 65536.
// If minPort == maxPort, port will be set to minPort.
func Peer(r *rand.Rand, prefix string, v6 bool, minPort, maxPort int) chihaya.Peer {
var (
port uint16
ip net.IP
)
if minPort <= 0 {
minPort = 1
}
if maxPort > 65536 {
maxPort = 65536
}
if maxPort < minPort {
maxPort = minPort
}
if len(prefix) > 20 {
prefix = prefix[:20]
}
if minPort == maxPort {
port = uint16(minPort)
} else {
port = uint16(r.Int63()%int64(maxPort-minPort)) + uint16(minPort)
}
if v6 {
b := make([]byte, 16)
ip = net.IP(b)
} else {
b := make([]byte, 4)
ip = net.IP(b)
}
for i := range ip {
b := r.Intn(254) + 1
ip[i] = byte(b)
}
prefix = prefix + AlphaNumericString(r, 20-len(prefix))
return chihaya.Peer{
ID: chihaya.PeerID(prefix),
Port: port,
IP: ip,
}
}

43
pkg/random/peer_test.go Normal file
View file

@ -0,0 +1,43 @@
// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package random
import (
"math/rand"
"net"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPeer(t *testing.T) {
r := rand.New(rand.NewSource(0))
for i := 0; i < 100; i++ {
minPort := 2000
maxPort := 2010
p := Peer(r, "", false, minPort, maxPort)
assert.Equal(t, 20, len(p.ID))
assert.True(t, p.Port >= uint16(minPort) && p.Port < uint16(maxPort))
assert.NotNil(t, p.IP.To4())
}
for i := 0; i < 100; i++ {
minPort := 2000
maxPort := 2010
p := Peer(r, "", true, minPort, maxPort)
assert.Equal(t, 20, len(p.ID))
assert.True(t, p.Port >= uint16(minPort) && p.Port < uint16(maxPort))
assert.True(t, len(p.IP) == net.IPv6len)
}
p := Peer(r, "abcdefghijklmnopqrst", false, 2000, 2000)
assert.Equal(t, "abcdefghijklmnopqrst", string(p.ID))
assert.Equal(t, uint16(2000), p.Port)
p = Peer(r, "abcdefghijklmnopqrstUVWXYZ", true, -10, -5)
assert.Equal(t, "abcdefghijklmnopqrst", string(p.ID))
assert.True(t, p.Port >= uint16(1) && p.Port <= uint16(65535))
}

26
pkg/random/string.go Normal file
View file

@ -0,0 +1,26 @@
// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package random
import "math/rand"
// AlphaNumeric is an alphabet with all lower- and uppercase letters and
// numbers.
const AlphaNumeric = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// AlphaNumericString is a shorthand for String(r, l, AlphaNumeric).
func AlphaNumericString(r rand.Source, l int) string {
return String(r, l, AlphaNumeric)
}
// String generates a random string of length l, containing only runes from
// the alphabet using the random source r.
func String(r rand.Source, l int, alphabet string) string {
b := make([]byte, l)
for i := range b {
b[i] = alphabet[r.Int63()%int64(len(alphabet))]
}
return string(b)
}

30
pkg/random/string_test.go Normal file
View file

@ -0,0 +1,30 @@
// Copyright 2016 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package random
import (
"math/rand"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestAlphaNumericString(t *testing.T) {
r := rand.NewSource(0)
s := AlphaNumericString(r, 0)
assert.Equal(t, 0, len(s))
s = AlphaNumericString(r, 10)
assert.Equal(t, 10, len(s))
for i := 0; i < 100; i++ {
s := AlphaNumericString(r, 10)
for _, c := range s {
assert.True(t, strings.Contains(AlphaNumeric, string(c)))
}
}
}