FAQ
Hey Gophers,

So I'm working on an application which allows two users to communicate
through a web server over websockets. The basic code looks like this:
(without all the sending code)

type (
Session struct {
Id uint64
Channel chan Message
}
Message struct {
From, To uint64
Body string
}
)
http.Handle("/connect", websocket.Server{
Handler: func(ws *websocket.Conn) {
defer ws.Close()

session := Session{
* Id: 0, // how to generate this?*
Channel: make(chan Message, 3),
}

defer func() {
leave <- session.Id
}()
join <- session

go func() {
for {
// receive
}
}()

for msg := range session.Channel {
// send
}
},
})


My question is what's the best way to generate the id such that it's not
obviously guessable?

Typically I'd use a UUID (and I may end up doing that), but I was curious
if there were a way to generate uint64s in an unpredictable fashion and
guarantee uniqueness (at least until it loops back around).

I was thinking of using SipHash with an ever increasing uint64 like this:

var idGenerator = make(chan uint64)
func generateIds() {
var k0, k1 uint64
err := binary.Read(rand.Reader, binary.BigEndian, &k0)
if err != nil {
panic(err)
}
err = binary.Read(rand.Reader, binary.BigEndian, &k1)
if err != nil {
panic(err)
}

var i uint64
p := make([]byte, 8)
for {
binary.BigEndian.PutUint64(p, i)
idGenerator <- siphash.Hash(k0, k1, p)
i++
}
}


Is that sound? Any other ideas?

- Caleb

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Jan Mercl at Jan 16, 2014 at 9:03 pm

    On Thu, Jan 16, 2014 at 9:01 PM, Caleb Doxsey wrote:
    My question is what's the best way to generate the id such that it's not
    obviously guessable?

    Typically I'd use a UUID (and I may end up doing that), but I was curious if
    there were a way to generate uint64s in an unpredictable fashion and
    guarantee uniqueness (at least until it loops back around).
    Seems like a potential use case of a full cycle[0] PRNG. You might
    want to have a look at [1] or [2].

       [0]: http://en.wikipedia.org/wiki/Full_cycle
       [1]: http://godoc.org/github.com/cznic/mathutil#FC32
       [2]: http://godoc.org/github.com/cznic/mathutil#FCBig

    -j

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Jan 16, 2014 at 10:48 pm

    On Jan 16, 2014 4:03 PM, "Jan Mercl" wrote:
    On Thu, Jan 16, 2014 at 9:01 PM, Caleb Doxsey wrote:
    My question is what's the best way to generate the id such that it's not
    obviously guessable?

    Typically I'd use a UUID (and I may end up doing that), but I was
    curious if
    there were a way to generate uint64s in an unpredictable fashion and
    guarantee uniqueness (at least until it loops back around).
    Seems like a potential use case of a full cycle[0] PRNG. You might
    want to have a look at [1] or [2].

    [0]: http://en.wikipedia.org/wiki/Full_cycle
    [1]: http://godoc.org/github.com/cznic/mathutil#FC32
    [2]: http://godoc.org/github.com/cznic/mathutil#FCBig

    -j
    Great! It turns out that I also have a similar requirement, thank you very
    much for the package and Wikipedia pointer.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Kevin Gillette at Jan 17, 2014 at 12:41 am
    Great package Jan! I don't have their particular problem, but I do have a
    few things that I could use a full cycle PRNG for.
    On Thursday, January 16, 2014 2:02:22 PM UTC-7, Jan Mercl wrote:
    On Thu, Jan 16, 2014 at 9:01 PM, Caleb Doxsey wrote:
    My question is what's the best way to generate the id such that it's not
    obviously guessable?

    Typically I'd use a UUID (and I may end up doing that), but I was
    curious if
    there were a way to generate uint64s in an unpredictable fashion and
    guarantee uniqueness (at least until it loops back around).
    Seems like a potential use case of a full cycle[0] PRNG. You might
    want to have a look at [1] or [2].

    [0]: http://en.wikipedia.org/wiki/Full_cycle
    [1]: http://godoc.org/github.com/cznic/mathutil#FC32
    [2]: http://godoc.org/github.com/cznic/mathutil#FCBig

    -j
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Hotei at Jan 16, 2014 at 9:57 pm
    Off the top of my head I'd suggest seeding your usual pseudo-random number
    source with /dev/urandom if you have a decent entropy source. The crypto
    package docs could give you more info.
    On Thursday, January 16, 2014 3:01:38 PM UTC-5, Caleb Doxsey wrote:

    Hey Gophers,

    So I'm working on an application which allows two users to communicate
    through a web server over websockets. The basic code looks like this:
    (without all the sending code)

    type (
    Session struct {
    Id uint64
    Channel chan Message
    }
    Message struct {
    From, To uint64
    Body string
    }
    )
    http.Handle("/connect", websocket.Server{
    Handler: func(ws *websocket.Conn) {
    defer ws.Close()

    session := Session{
    * Id: 0, // how to generate this?*
    Channel: make(chan Message, 3),
    }

    defer func() {
    leave <- session.Id
    }()
    join <- session

    go func() {
    for {
    // receive
    }
    }()

    for msg := range session.Channel {
    // send
    }
    },
    })


    My question is what's the best way to generate the id such that it's not
    obviously guessable?

    Typically I'd use a UUID (and I may end up doing that), but I was curious
    if there were a way to generate uint64s in an unpredictable fashion and
    guarantee uniqueness (at least until it loops back around).

    I was thinking of using SipHash with an ever increasing uint64 like this:

    var idGenerator = make(chan uint64)
    func generateIds() {
    var k0, k1 uint64
    err := binary.Read(rand.Reader, binary.BigEndian, &k0)
    if err != nil {
    panic(err)
    }
    err = binary.Read(rand.Reader, binary.BigEndian, &k1)
    if err != nil {
    panic(err)
    }

    var i uint64
    p := make([]byte, 8)
    for {
    binary.BigEndian.PutUint64(p, i)
    idGenerator <- siphash.Hash(k0, k1, p)
    i++
    }
    }


    Is that sound? Any other ideas?

    - Caleb
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Maxim Khitrov at Jan 16, 2014 at 11:58 pm
    First, unless you're using something like Jan's full cycle PRNG, be
    aware of the birthday problem when using random 64-bit ids. Depending
    on how frequently they are being generated, you may need a few extra
    bits to prevent collisions:

    http://en.wikipedia.org/wiki/Birthday_problem

    Second, if the hardware supports AES-NI, that may be the best option.
    Get 128-bit key and iv from crypto/rand and just run AES in counter
    mode:

    http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
    http://play.golang.org/p/R4UtOE3-LN

    You could speed this up by skipping the actual XOR operation and using
    the AES output directly. You'll need to increment the counter (AES
    block input) yourself in this case.
    On Thu, Jan 16, 2014 at 3:01 PM, Caleb Doxsey wrote:
    Hey Gophers,

    So I'm working on an application which allows two users to communicate
    through a web server over websockets. The basic code looks like this:
    (without all the sending code)

    type (
    Session struct {
    Id uint64
    Channel chan Message
    }
    Message struct {
    From, To uint64
    Body string
    }
    )
    http.Handle("/connect", websocket.Server{
    Handler: func(ws *websocket.Conn) {
    defer ws.Close()

    session := Session{
    Id: 0, // how to generate this?
    Channel: make(chan Message, 3),
    }

    defer func() {
    leave <- session.Id
    }()
    join <- session

    go func() {
    for {
    // receive
    }
    }()

    for msg := range session.Channel {
    // send
    }
    },
    })


    My question is what's the best way to generate the id such that it's not
    obviously guessable?

    Typically I'd use a UUID (and I may end up doing that), but I was curious if
    there were a way to generate uint64s in an unpredictable fashion and
    guarantee uniqueness (at least until it loops back around).

    I was thinking of using SipHash with an ever increasing uint64 like this:

    var idGenerator = make(chan uint64)
    func generateIds() {
    var k0, k1 uint64
    err := binary.Read(rand.Reader, binary.BigEndian, &k0)
    if err != nil {
    panic(err)
    }
    err = binary.Read(rand.Reader, binary.BigEndian, &k1)
    if err != nil {
    panic(err)
    }

    var i uint64
    p := make([]byte, 8)
    for {
    binary.BigEndian.PutUint64(p, i)
    idGenerator <- siphash.Hash(k0, k1, p)
    i++
    }
    }


    Is that sound? Any other ideas?

    - Caleb

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 16, '14 at 8:01p
activeJan 17, '14 at 12:41a
posts6
users6
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase