Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# essentials - aah framework
[![Build Status](https://travis-ci.org/go-aah/essentials.svg?branch=master)](https://travis-ci.org/go-aah/essentials) [![codecov](https://codecov.io/gh/go-aah/essentials/branch/master/graph/badge.svg)](https://codecov.io/gh/go-aah/essentials/branch/master) [![Go Report Card](https://goreportcard.com/badge/aahframework.org/essentials.v0)](https://goreportcard.com/report/aahframework.org/essentials.v0)
[![Version](https://img.shields.io/badge/version-0.4-blue.svg)](https://github.com/go-aah/essentials/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/essentials.v0?status.svg)](https://godoc.org/aahframework.org/essentials.v0) [![License](https://img.shields.io/github/license/go-aah/essentials.svg)](LICENSE)
[![Version](https://img.shields.io/badge/version-0.5-blue.svg)](https://github.com/go-aah/essentials/releases/latest) [![GoDoc](https://godoc.org/aahframework.org/essentials.v0?status.svg)](https://godoc.org/aahframework.org/essentials.v0) [![License](https://img.shields.io/github/license/go-aah/essentials.svg)](LICENSE)

***v0.4 [released](https://github.com/go-aah/essentials/releases/latest) and tagged on Mar 30, 2017***
***v0.5 [released](https://github.com/go-aah/essentials/releases/latest) and tagged on Apr 07, 2017***

`essentials` contains simple & useful utils methods for Go. aah framework utilizes essentials (aka `ess`) library across. Essentials library complements with handy methods, refer godoc to know more about methods:
* filepath
* GUID (Globally Unique Identifier)
* random string, random byte generation at fixed length
* go
* io
* os
Expand Down
42 changes: 42 additions & 0 deletions archive_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
// go-aah/essentials source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package ess

import (
"io/ioutil"
"testing"

"aahframework.org/test.v0/assert"
)

func TestArchiveZip(t *testing.T) {
// Prepare data for zip file
testdataPath := getTestdataPath()
path1 := join(testdataPath, "dirpaths", "level1", "level2", "level3")
path11 := join(testdataPath, "dirpaths", "level1", "level1-1")
path12 := join(testdataPath, "dirpaths", "level1", "level1-2")
path21 := join(testdataPath, "dirpaths", "level1", "level2", "level2-1")
path22 := join(testdataPath, "dirpaths", "level1", "level2", "level2-2")
defer DeleteFiles(join(testdataPath, "dirpaths"))

_ = MkDirAll(path1, 0755)
_ = MkDirAll(path11, 0755)
_ = MkDirAll(path12, 0755)
_ = MkDirAll(path21, 0755)
_ = MkDirAll(path22, 0755)

_ = ioutil.WriteFile(join(path1, "file1.txt"), []byte("file1.txt"), 0600)
_ = ioutil.WriteFile(join(path11, "file11.txt"), []byte("file11.txt"), 0600)
_ = ioutil.WriteFile(join(path12, "file12.txt"), []byte("file12.txt"), 0600)
_ = ioutil.WriteFile(join(path21, "file21.txt"), []byte("file21.txt"), 0600)
_ = ioutil.WriteFile(join(path22, "file22.txt"), []byte("file22.txt"), 0600)

zipName := join(testdataPath, "testarchive.zip")
defer DeleteFiles(zipName)

err := Zip(zipName, join(testdataPath, "dirpaths"))
assert.Nil(t, err)
assert.True(t, IsFileExists(zipName))
}
2 changes: 1 addition & 1 deletion essentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
package ess

// Version no. of essentials library
var Version = "0.4"
var Version = "0.5"
97 changes: 97 additions & 0 deletions random_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
// go-aah/essentials source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package ess

import (
"crypto/rand"
"encoding/hex"
"io"
mrand "math/rand"
"sync"
"time"
)

const (
letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)

var (
mRandSrc mrand.Source
mr *sync.Mutex
)

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Random String methods
//___________________________________

// RandomString method generates the random string for given length using
// `crypto/rand`.
func RandomString(length int) string {
return hex.EncodeToString(GenerateRandomKey(length / 2))
}

// RandomStringbm method generates the random string for given length using
// `math/rand.Source` and byte mask.
func RandomStringbm(length int) string {
return string(GenerateRandomKeybm(length))
}

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Random key methods
//___________________________________

// GenerateRandomKey method generates the random bytes for given length using
// `crypto/rand`.
func GenerateRandomKey(length int) []byte {
k := make([]byte, length)
if _, err := io.ReadFull(rand.Reader, k); err != nil {
// fallback to math based random key generater
return GenerateRandomKeybm(length)
}
return k
}

// GenerateRandomKeybm method generates the random bytes for given length using
// `math/rand.Source` and byte mask.
// StackOverflow Ref - http://stackoverflow.com/a/31832326
func GenerateRandomKeybm(length int) []byte {
b := make([]byte, length)
// A randSrc() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := length-1, randSrc(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = randSrc(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}

return b
}

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// Unexported methods
//___________________________________

func randSrc() int64 {
mr.Lock()
defer mr.Unlock()
return mRandSrc.Int63()
}

//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
// init
//___________________________________

func init() {
mRandSrc = mrand.NewSource(time.Now().UnixNano())
mr = &sync.Mutex{}
}
43 changes: 43 additions & 0 deletions random_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Jeevanandam M. (https://github.com/jeevatkm)
// go-aah/essentials source code and usage is governed by a MIT style
// license that can be found in the LICENSE file.

package ess

import (
"testing"

"aahframework.org/test.v0/assert"
)

func TestEssRandomKey(t *testing.T) {
key1 := GenerateRandomKey(32)
assert.NotNil(t, key1)
assert.True(t, len(key1) == 32)

key2 := GenerateRandomKeybm(64)
assert.NotNil(t, key2)
assert.True(t, len(key2) == 64)
}

func TestEssRandomString(t *testing.T) {
str1 := RandomString(32)
assert.True(t, len(str1) == 32)
assert.NotNil(t, str1)

str2 := RandomStringbm(32)
assert.True(t, len(str2) == 32)
assert.NotNil(t, str2)
}

func BenchmarkGenerateRandomKey(b *testing.B) {
for i := 0; i < b.N; i++ {
GenerateRandomKey(16)
}
}

func BenchmarkGenerateRandomKeybm(b *testing.B) {
for i := 0; i < b.N; i++ {
GenerateRandomKeybm(32)
}
}