Skip to content

Commit

Permalink
Support of --suffix=xxx, --keep-beginning and --keep-end (fix #4)
Browse files Browse the repository at this point in the history
  • Loading branch information
moul committed Oct 14, 2015
1 parent fed164a commit 1f63158
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Using go

### master (unreleased)

* Support of `--suffix=xxx`, `--keep-beginning` and `--keep-end` options ([#4](https://github.com/moul/anonuuid/issues/4))
* Using **party** to stabilize vendor package versions ([#8](https://github.com/moul/anonuuid/issues/8))
* Add homebrew package ([#6](https://github.com/moul/anonuuid/issues/6))

Expand Down
42 changes: 42 additions & 0 deletions anonuuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,17 @@ type AnonUUID struct {
// Prefix will be the beginning of all the generated UUIDs
Prefix string

// Suffix will be the end of all the generated UUIDs
Suffix string

// AllowNonUUIDInput tells FakeUUID to accept non UUID input string
AllowNonUUIDInput bool

// KeepBeginning tells FakeUUID to let the beginning of the UUID as it is
KeepBeginning bool

// KeepEnd tells FakeUUID to let the last part of the UUID as it is
KeepEnd bool
}

// Sanitize takes a string as input and return sanitized string
Expand All @@ -51,13 +60,28 @@ func (a *AnonUUID) FakeUUID(input string) string {
}
if _, ok := a.cache[input]; !ok {

if a.KeepBeginning {
a.Prefix = input[:8]
}

if a.KeepEnd {
a.Suffix = input[36-12:]
}

if a.Prefix != "" {
matched, err := regexp.MatchString("^[a-z0-9]+$", a.Prefix)
if err != nil || !matched {
a.Prefix = "invalidprefix"
}
}

if a.Suffix != "" {
matched, err := regexp.MatchString("^[a-z0-9]+$", a.Suffix)
if err != nil || !matched {
a.Suffix = "invalsuffix"
}
}

var fakeUUID string
var err error
if a.Hexspeak {
Expand All @@ -78,6 +102,13 @@ func (a *AnonUUID) FakeUUID(input string) string {
}
}

if a.Suffix != "" {
fakeUUID, err = SuffixUUID(a.Suffix, fakeUUID)
if err != nil {
panic(err)
}
}

// FIXME: check for duplicates and retry

a.cache[input] = fakeUUID
Expand Down Expand Up @@ -108,6 +139,17 @@ func PrefixUUID(prefix string, uuid string) (string, error) {
return prefixedUUID, nil
}

// SuffixUUID returns a suffixed UUID
func SuffixUUID(suffix string, uuid string) (string, error) {
uuidLetters := uuid[:8] + uuid[9:13] + uuid[14:18] + uuid[19:23] + uuid[24:36]
uuidLetters = uuidLetters[:32-len(suffix)] + suffix
suffixedUUID, err := FormatUUID(uuidLetters)
if err != nil {
return "", err
}
return suffixedUUID, nil
}

// IsUUID returns nil if the input is an UUID, else it returns an error
func IsUUID(input string) error {
matched, err := regexp.MatchString("^"+UUIDRegex+"$", input)
Expand Down
205 changes: 205 additions & 0 deletions anonuuid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,211 @@ func TestAnonUUID_FakeUUID(t *testing.T) {
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--suffix=hello", func() {
anonuuid := New()

anonuuid.Suffix = "hello"

expected1 := "00000000-0000-1000-0000-0000000hello"
expected2 := "11111111-1111-1111-1111-1111111hello"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--suffix=helloworldhello", func() {
anonuuid := New()

anonuuid.Suffix = "helloworldhello"

expected1 := "00000000-0000-1000-0hel-loworldhello"
expected2 := "11111111-1111-1111-1hel-loworldhello"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--suffix=@@@", func() {
anonuuid := New()

anonuuid.Suffix = "@@@"

expected1 := "00000000-0000-1000-0000-0invalsuffix"
expected2 := "11111111-1111-1111-1111-1invalsuffix"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--prefix=hello --suffix=hello", func() {
anonuuid := New()

anonuuid.Prefix = "hello"
anonuuid.Suffix = "hello"

expected1 := "hello000-0000-1000-0100-0000000hello"
// FIXME: why this ^ ?
expected2 := "hello111-1111-1111-1111-1111111hello"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--prefix=helloworldhello --suffix=helloworldhello", func() {
anonuuid := New()

anonuuid.Prefix = "helloworldhello"
anonuuid.Suffix = "helloworldhello"

expected1 := "hellowor-ldhe-1lo0-0hel-loworldhello"
// FIXME: should not do this :)
expected2 := "hellowor-ldhe-1lo1-1hel-loworldhello"
// FIXME: should not do this :)

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--prefix=helloworldhello --suffix=@@@", func() {
anonuuid := New()

anonuuid.Prefix = "@@@"
anonuuid.Suffix = "@@@"

expected1 := "invalidp-refi-1000-0000-0invalsuffix"
expected2 := "invalidp-refi-1111-1111-1invalsuffix"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--keep-beginning", func() {
anonuuid := New()

anonuuid.KeepBeginning = true

expected1 := "15573749-0000-1000-0000-100000000000"
expected2 := "c245c3cb-1111-1111-1111-111111111111"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--keep-end", func() {
anonuuid := New()

anonuuid.KeepEnd = true

expected1 := "00000000-0000-1000-0000-16e79bed52e0"
expected2 := "11111111-1111-1111-1111-70cb1fe4eefe"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--keep-beginning --keep-end", func() {
anonuuid := New()

anonuuid.KeepBeginning = true
anonuuid.KeepEnd = true

expected1 := "15573749-0000-1000-0000-16e79bed52e0"
expected2 := "c245c3cb-1111-1111-1111-70cb1fe4eefe"

fakeuuid1 := anonuuid.FakeUUID(realuuid1)
fakeuuid2 := anonuuid.FakeUUID(realuuid1)
fakeuuid3 := anonuuid.FakeUUID(realuuid2)
fakeuuid4 := anonuuid.FakeUUID(realuuid2)
fakeuuid5 := anonuuid.FakeUUID(realuuid1)

So(len(anonuuid.cache), ShouldEqual, 2)
So(fakeuuid1, ShouldEqual, fakeuuid2)
So(fakeuuid1, ShouldEqual, fakeuuid5)
So(fakeuuid3, ShouldEqual, fakeuuid4)
So(fakeuuid2, ShouldNotEqual, fakeuuid3)
So(fakeuuid1, ShouldEqual, expected1)
So(fakeuuid3, ShouldEqual, expected2)
})
Convey("--hexspeak", func() {
anonuuid := New()

Expand Down
15 changes: 15 additions & 0 deletions cmd/anonuuid/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,22 @@ func main() {
Name: "random, r",
Usage: "Generate random fake UUIDs",
},
cli.BoolFlag{
Name: "keep-beginning",
Usage: "Keep first part of the UUID unchanged",
},
cli.BoolFlag{
Name: "keep-end",
Usage: "Keep last part of the UUID unchanged",
},
cli.StringFlag{
Name: "prefix, p",
Usage: "Prefix generated UUIDs",
},
cli.StringFlag{
Name: "suffix",
Usage: "Suffix generated UUIDs",
},
}

app.Action = action
Expand All @@ -46,6 +58,9 @@ func action(c *cli.Context) {
anonuuid.Hexspeak = c.Bool("hexspeak")
anonuuid.Random = c.Bool("random")
anonuuid.Prefix = c.String("prefix")
anonuuid.Suffix = c.String("suffix")
anonuuid.KeepBeginning = c.Bool("keep-beginning")
anonuuid.KeepEnd = c.Bool("keep-end")

for scanner.Scan() {
line := scanner.Text()
Expand Down

0 comments on commit 1f63158

Please sign in to comment.