Coder Social home page Coder Social logo

go-hashids's Introduction

go-hashids Build Status GoDoc

Go (golang) v1 implementation of http://www.hashids.org under MIT License (same as the original implementations)

Original implementations by Ivan Akimov

Setup

go get github.com/speps/go-hashids/v2

CLI tool :

go get github.com/speps/go-hashids/v2/cmd/hashid

Example

package main

import "fmt"
import "github.com/speps/go-hashids/v2"

func main() {
	hd := hashids.NewData()
	hd.Salt = "this is my salt"
	hd.MinLength = 30
	h, _ := hashids.NewWithData(hd)
	e, _ := h.Encode([]int{45, 434, 1313, 99})
	fmt.Println(e)
	d, _ := h.DecodeWithError(e)
	fmt.Println(d)
}

Thanks to all the contributors

Let me know if I forgot anyone of course.

Changelog

2021/05/04

  • v2.0.1 - Added module support with /v2 suffix

2017/05/09

  • Changed API
    • New methods now return errors
    • Added sanity check in Decode that makes sure that the salt is consistent

2014/09/13

  • Updated to Hashids v1.0.0 (should be compatible with other implementations, let me know if not, was checked against the Javascript version)
  • Changed API
    • Encrypt/Decrypt are now Encode/Decode
    • HashID is now constructed from HashIDData containing alphabet, salt and minimum length

go-hashids's People

Contributors

baijum avatar cgt avatar dolmen avatar haarts avatar hypnobrando avatar matthewvalimaki avatar md2perpe avatar mfridman avatar mingrammer avatar pconcepcion avatar peterhellberg avatar roosmaa avatar speps avatar zouxifeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-hashids's Issues

min length

what is min length can i use to have unique ids ?

Create v2.0.1, a valid go module version

Tag v2.0.0 exists, but it is not valid to make a clean Go module version: v2.0.0 is listed as "incompatible".

Here is the process to create a v2.0.1 that would fix the problem:

  1. Fix the module go.mod to add a /v2 suffix
  2. Tag v2.0.1
sed -i '' '1s!.*!module github.com/speps/go-hashids/v2!' go.mod
git add go.mod
git commit -m "Fix go module to add /v2 suffix #57"
git tag v2.0.1
git push origin v2.0.1

Ignoring NewWithData error leads to runtime errors

With introduction of NewWithData returning error vs panic there's now a chance of runtime error if the error is ignored. Say you have an alphabet with two same characters (causes error to be thrown) and you choose to ignore the error and continue with h.Encode() it will lead to runtime error because (h *HashID) is nil. Readme example by default ignores the error.

While of course it is bad practice to ignore errors I wonder if all exported functions needs check if h == nil. Only reason why I am thinking about such an implementation is because the library is small (easy to implement such check) and because the library can play a crucial part of web application setup. Rather than dying without error message it would be nice to have message saying why something failed.

Uint32 and Uint64 version

Will there be a UInt32 and UInt64 version for these:

func (h *HashID) Encode(numbers []int) (string, error)
func (h *HashID) EncodeInt64(numbers []int64) (string, error)

Obviously it may create incompatibilities with eg PHP version of library but for some people that is irrelevant.

Not compatible with JS/PHP version

If you use the Salt like "\xcb\x91\x96\xd0\xa7\x36\x91\x5b\xbf\xd4" the output of both the JS and PHP version is the same (haven't tested other libraries) but the output of his library is completely different

Can it encode string?

Can it encode string?
When i try it with a sting([]byte) with a small MinLength, it returned a long string.

some bug on bit int

Hi
I am trying to use hashids on golang and big int , the length of number is 18, length of alphabet is 62.
Encode and decode is work.
But decode result is wrong. just like that:
243253735426375465
decode result is
243253735426375464
or
243253735426375445

Bump go1 branch

Since code in master is considered 1.0.0, the go1 branch (which go get pulls by default) should be updated to use this new stable version.

hashing uuids?

I saw that hashid intentionally doesn't support encoding strings because it's not secure, but I was wondering about hashing uuids as a way to shorten them (not for security). is that possible with this library? thanks!

Push a new tag please

Hi, the release version v1.0.0 is too old. Could you please make a new tag for the newest commit ?
How about v2.0.0 because there is a breaking change since 2017/05/09. Thank you.

Where's the curse word protection?

I don't see the curse word protection implemented. Am I missing something? Or maybe it's planned for later? In my testing with a non-default alphabet, I was seeing letter sequences that the hashids.org website says will not occur. The hashids.org website has the following in the documentation:

%@&


This code was written with the intent of placing generated hashes in visible places - like the URL.

Therefore, the algorithm tries to avoid generating most common English curse words by never placing the following letters next to each other:

c, C, s, S, f, F, h, H, u, U, i, I, t, T

Use uint64 instead of int64

go-hashids provides EncodeInt64 but it actually rejects negative numbers in below. Does it make sense to use uint64, or provides a uint64 variant?

// EncodeInt64 hashes an array of int64 to a string containing at least MinLength characters taken from the Alphabet.
// Use DecodeInt64 using the same Alphabet and Salt to get back the array of int64.
func (h *HashID) EncodeInt64(numbers []int64) (string, error) {
	if len(numbers) == 0 {
		return "", errors.New("encoding empty array of numbers makes no sense")
	}
	for _, n := range numbers {
		if n < 0 {
			return "", errors.New("negative number not supported")
		}
	}

I'm using go-hashids along with hashids' Ruby implementation. In some cases, go-hashids rejects inputs that exceed MaxInt, while the Ruby implementation can handle it because Ruby's Integer can be larger than Go's MaxInt.

I made a fork to workaround the issue and happy to upstream something like this.

https://github.com/kzys/go-hashids/

Panics instead of returning an error

Instead of returning an error as is the convention in Go, this library panics when it encounters (non-exceptional) errors. A function being passed bad input is not exceptional, it is to be expected, and so an error should be returned if it happens.

Fix for #28 just broke MinLength

This should not fail, and it never used to, but now it does.
The hashid with min length 20 fails to decode the encoded string of length 30.

func TestHashids(t *testing.T) {

	// MinLength 30
	hData30 := hashids.NewData()
	hData30.Salt = "blarg123"
	hData30.MinLength = 30
	h30, err := hashids.NewWithData(hData30)
	if err != nil {
		t.Error(err)
	}

	encoded30, err := h30.EncodeInt64([]int64{4})
	if err != nil {
		t.Error(err)
	}
	decoded30, err := h30.DecodeInt64WithError(encoded30)
	if err != nil {
		t.Error(err)
	}
	if len(decoded30) != 1 || decoded30[0] != []int64{4}[0] {
		t.Error("Expected: ", []int64{4}, "; Got: ", decoded30)
	}

	// Same hashid, but minLength 20
	hData20 := hashids.NewData()
	hData20.Salt = "blarg123"
	hData20.MinLength = 20
	h20, err := hashids.NewWithData(hData20)
	if err != nil {
		t.Error(err)
	}

	// Should still be able to decode, as the only change is MinLength
	decoded20, err := h20.DecodeInt64WithError(encoded30)
	if err != nil {
		t.Error(err)
	}
	if len(decoded20) != 1 || decoded20[0] != []int64{4}[0] {
		t.Error("Expected: ", []int64{4}, "; Got: ", decoded20)
	}
}

import error

image

step:
go get github.com/speps/go-hashids

error:
cannot resolve file 'go-hashids',but file exist

Minimum Alphabet Length

What is the consequence of changing the minimum alphabet length to 10.

I want my alphabet to be "0123456789"?

I changed your code. I only want to encode numbers and it seems to work.

DecodingWithError does not produce error

Using TestDecodeWithError on https://github.com/speps/go-hashids/blob/master/hashids_test.go#L163 I noticed that it fails and no error is produced if I do the following:

hdata.Alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
dec, err := hid.DecodeWithError("")

However if I use hdata.Alphabet = "PleasAkMEFoThStx" that is currently in the test it works.
Depending on the hash dec is either [] or [some number].

My expectation here was to see an error and [].

Epoch hashing

Hi Team,

I don't know whether or not you think this is a valid bug or not.

If I do something like:

// HashMaker performs a salted hash based upon epoch
func HashMaker() string {
	now := time.Now()
	hash := hashids.NewData()
	value := now.Unix()
	hash.Salt = "hello world"
	h, _ := hashids.NewWithData(hash)
	e, _ := h.Encode(toIntSlice(string(value)))
	got, _ := h.DecodeWithError(e)
	fmt.Println("should be", value, "got", got)

	return e
}

I get something like:

should be 1538515448 got [65533]
jolM
should be 1538515449 got [65533]
jolM
should be 1538515450 got [65533]
jolM
should be 1538515451 got [65533]
jolM

I guess that my expectation is to see something like:

should be <epoch> got <epoch>
<hash>

I am sending the epoch as a string into the hash as data, and I can replace it for the salt as well, and it results in the same problem.

allow numbers only alphabet

Current implementation fails if we use numeric only alphabet.
But from an algorithm perspective it should be working.

Please add a release tag (for better compatibility with go dep)

go-hashids has one release tag, 1.0.0

There are a few changes to master -- most notably the prototype change to NewWithData() from issue #29 -- that postdate the 1.0.0 tag.

When I added go dep vendoring to a project that depends on hashids, it pulled the 1.0.0 release instead of the latest master, this breaking my build.

This was an easy fix via a dep override, but it'd be nice to have the current master version tagged, since that's probably what most people are using anyway, and it'll save a few minutes of vendoring hassle.

How to just hash 1 id

Hi I only want to hash 1 value at a time. The built in function seems to only support an array of int as input.

Decode shouldn't panic

Hashed ids are often used as part of urls. They are outside of program's control (e.g. a user on the website might manually modify url).

If such modified value is passed to Decode(), it'll panic, which is against Go conventions, see http://blog.golang.org/defer-panic-and-recover:

The convention in the Go libraries is that even when a package uses panic internally, its external API still presents explicit error return values.

It would be better if it was Decode(hash string) ([]int, error).

This would require breaking the API, which might not be a good idea, so an alternative would be to provide additional DecodeSafe (not a great name) or IsValid(hash string) bool so that the string can be checked for correctness before calling Decode().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.