Skip to content

Commit eef8da7

Browse files
authored
Encode the SIO socketID generated prefix (#73)
The prefix is encoded to present ASCII characters during logging. The unicode characters can still be seen, by using GoString() or the "%#v" formatting function for the `log` and `fmt` Printf() function. The prefix generator function was refactored to accept an injected date, for testing purposes. Updating the prefix via a user function has not been implemented, as the ID type needs to change to accommodate this request. Providing a user function will be in a future commit.
1 parent 9f1e56c commit eef8da7

File tree

3 files changed

+202
-16
lines changed

3 files changed

+202
-16
lines changed

Diff for: server.go

+23-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package socketio
22

33
import (
4+
"encoding/hex"
45
"math/rand"
56
"net/http"
7+
"time"
68

79
eios "github.com/njones/socketio/engineio/session"
810
seri "github.com/njones/socketio/serialize"
@@ -66,22 +68,28 @@ type rawTransport interface {
6668
Transport(siot.SocketID) *siot.Transport
6769
}
6870

69-
func socketIDQuickPrefix() string {
70-
src := rand.NewSource(42)
71-
rnd := rand.New(src)
71+
var _socketIDQuickPrefix = func(now time.Time) func() string {
72+
return func() string {
73+
src := rand.NewSource(now.UnixNano())
74+
rnd := rand.New(src)
7275

73-
cards := [][]rune{
74-
{127137, 127150}, // spades
75-
{127153, 127166}, // hearts
76-
{127169, 127182}, // diamonds
77-
{127185, 127198}, // clubs
78-
}
76+
cards := [][]rune{
77+
{127137, 127150}, // spades
78+
{127153, 127166}, // hearts
79+
{127169, 127182}, // diamonds
80+
{127185, 127198}, // clubs
81+
}
82+
83+
prefix := make([]rune, 5)
84+
for i := range prefix {
85+
suit := rnd.Intn(4)
86+
card := int32(rnd.Intn(int(cards[suit][1]-cards[suit][0]-1))) + cards[suit][0]
87+
prefix[i] = card
88+
}
7989

80-
prefix := make([]rune, 5)
81-
for i := range prefix {
82-
suit := rnd.Intn(4)
83-
card := int32(rnd.Intn(int(cards[suit][1]-cards[suit][0]-1))) + cards[suit][0]
84-
prefix[i] = card
90+
enc := hex.EncodeToString([]byte(string(prefix)))
91+
return enc + "::"
8592
}
86-
return string(prefix) + "::"
8793
}
94+
95+
var socketIDQuickPrefix = _socketIDQuickPrefix(time.Now())

Diff for: server_benchmark_test.go

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package socketio
2+
3+
import (
4+
"crypto/md5"
5+
"encoding/base32"
6+
"encoding/base64"
7+
"encoding/hex"
8+
"fmt"
9+
"hash/crc32"
10+
"math/rand"
11+
"strconv"
12+
"testing"
13+
"time"
14+
15+
sios "github.com/njones/socketio/session"
16+
"github.com/stretchr/testify/assert"
17+
)
18+
19+
func TestSocketIDQuickPrefix(t *testing.T) {
20+
now := time.Date(1946, time.February, 14, 10, 00, 00, 00, time.UTC) // February 14, 1946 - The date ENIAC was demonstrated to the world
21+
socketID := sios.ID(_socketIDQuickPrefix(now)() + "ABC123def456")
22+
23+
assert.Equal(t, sios.ID("f09f838af09f8384f09f839bf09f8387f09f8396::ABC123def456"), socketID)
24+
assert.Equal(t, "f09f838af09f8384f09f839bf09f8387f09f8396::ABC123def456", socketID.String())
25+
assert.Equal(t, "f09f838af09f8384f09f839bf09f8387f09f8396::ABC123def456", fmt.Sprintf("%s", socketID))
26+
assert.Equal(t, "🃊🃄🃛🃇🃖::ABC123def456", socketID.GoString())
27+
assert.Equal(t, "🃊🃄🃛🃇🃖::ABC123def456", fmt.Sprintf("%#v", socketID))
28+
}
29+
30+
func socketIDQuickPrefix32() string {
31+
src := rand.NewSource(time.Now().UnixNano())
32+
rnd := rand.New(src)
33+
34+
cards := [][]rune{
35+
{127137, 127150}, // spades
36+
{127153, 127166}, // hearts
37+
{127169, 127182}, // diamonds
38+
{127185, 127198}, // clubs
39+
}
40+
41+
prefix := make([]rune, 5)
42+
for i := range prefix {
43+
suit := rnd.Intn(4)
44+
card := int32(rnd.Intn(int(cards[suit][1]-cards[suit][0]-1))) + cards[suit][0]
45+
prefix[i] = card
46+
}
47+
48+
enc := base32.HexEncoding.EncodeToString([]byte(string(prefix)))
49+
return enc + "::"
50+
}
51+
52+
func socketIDQuickPrefix64() string {
53+
src := rand.NewSource(time.Now().UnixNano())
54+
rnd := rand.New(src)
55+
56+
cards := [][]rune{
57+
{127137, 127150}, // spades
58+
{127153, 127166}, // hearts
59+
{127169, 127182}, // diamonds
60+
{127185, 127198}, // clubs
61+
}
62+
63+
prefix := make([]rune, 5)
64+
for i := range prefix {
65+
suit := rnd.Intn(4)
66+
card := int32(rnd.Intn(int(cards[suit][1]-cards[suit][0]-1))) + cards[suit][0]
67+
prefix[i] = card
68+
}
69+
70+
enc := base64.StdEncoding.EncodeToString([]byte(string(prefix)))
71+
return enc + "::"
72+
}
73+
74+
func socketIDQuickPrefixHex() string {
75+
src := rand.NewSource(time.Now().UnixNano())
76+
rnd := rand.New(src)
77+
78+
cards := [][]rune{
79+
{127137, 127150}, // spades
80+
{127153, 127166}, // hearts
81+
{127169, 127182}, // diamonds
82+
{127185, 127198}, // clubs
83+
}
84+
85+
prefix := make([]rune, 5)
86+
for i := range prefix {
87+
suit := rnd.Intn(4)
88+
card := int32(rnd.Intn(int(cards[suit][1]-cards[suit][0]-1))) + cards[suit][0]
89+
prefix[i] = card
90+
}
91+
92+
enc := hex.EncodeToString([]byte(string(prefix)))
93+
return enc + "::"
94+
}
95+
96+
func socketIDQuickPrefixMD5() string {
97+
src := rand.NewSource(time.Now().UnixNano())
98+
rnd := rand.New(src)
99+
100+
cards := [][]rune{
101+
{127137, 127150}, // spades
102+
{127153, 127166}, // hearts
103+
{127169, 127182}, // diamonds
104+
{127185, 127198}, // clubs
105+
}
106+
107+
prefix := make([]rune, 5)
108+
for i := range prefix {
109+
suit := rnd.Intn(4)
110+
card := int32(rnd.Intn(int(cards[suit][1]-cards[suit][0]-1))) + cards[suit][0]
111+
prefix[i] = card
112+
}
113+
114+
hsh := md5.Sum([]byte(string(prefix)))
115+
return string(hsh[:]) + "::"
116+
}
117+
118+
func socketIDQuickPrefixCRC32() string {
119+
src := rand.NewSource(time.Now().UnixNano())
120+
rnd := rand.New(src)
121+
122+
cards := [][]rune{
123+
{127137, 127150}, // spades
124+
{127153, 127166}, // hearts
125+
{127169, 127182}, // diamonds
126+
{127185, 127198}, // clubs
127+
}
128+
129+
prefix := make([]rune, 5)
130+
for i := range prefix {
131+
suit := rnd.Intn(4)
132+
card := int32(rnd.Intn(int(cards[suit][1]-cards[suit][0]-1))) + cards[suit][0]
133+
prefix[i] = card
134+
}
135+
136+
i := crc32.ChecksumIEEE([]byte(string(prefix)))
137+
return strconv.FormatUint(uint64(i), 10) + "::"
138+
}
139+
140+
func BenchmarkSocketIDPrefixEncoding32(b *testing.B) {
141+
for n := 0; n < b.N; n++ {
142+
socketIDQuickPrefix32()
143+
}
144+
}
145+
146+
func BenchmarkSocketIDPrefixEncoding64(b *testing.B) {
147+
for n := 0; n < b.N; n++ {
148+
socketIDQuickPrefix64()
149+
}
150+
}
151+
152+
func BenchmarkSocketIDPrefixEncodingHex(b *testing.B) {
153+
for n := 0; n < b.N; n++ {
154+
socketIDQuickPrefixHex()
155+
}
156+
}
157+
158+
func BenchmarkSocketIDPrefixEncodingMD5(b *testing.B) {
159+
for n := 0; n < b.N; n++ {
160+
socketIDQuickPrefixMD5()
161+
}
162+
}
163+
164+
func BenchmarkSocketIDPrefixEncodingCRC32(b *testing.B) {
165+
for n := 0; n < b.N; n++ {
166+
socketIDQuickPrefixMD5()
167+
}
168+
}

Diff for: session/session.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@ package session
33
import (
44
"crypto/rand"
55
"encoding/base64"
6+
"encoding/hex"
7+
"strings"
68
)
79

810
type ID string
911

10-
func (id ID) String() string { return string(id) }
12+
func (id ID) String() string { return string(id) }
13+
func (id ID) GoString() string {
14+
if b, a, found := strings.Cut(string(id), "::"); found {
15+
if str, err := hex.DecodeString(b); err == nil {
16+
return string(str) + "::" + a
17+
}
18+
}
19+
return string(id)
20+
}
1121
func (id ID) Room(prefix string) string { return prefix + string(id) }
1222

1323
var GenerateID = func(string) ID {

0 commit comments

Comments
 (0)