func CryptoRandom(count int, start int, end int, letters bool, numbers bool, chars ...rune) (string, error) {
	if count == 0 {
		return "", nil
	} else if count < 0 {
		err := fmt.Errorf("randomstringutils illegal argument: Requested random string length %v is less than 0.", count)  
		return "", err
	}
	if chars != nil && len(chars) == 0 {
		err := fmt.Errorf("randomstringutils illegal argument: The chars array must not be empty")
		return "", err
	}
	if start == 0 && end == 0 {
		if chars != nil {
			end = len(chars)
		} else {
			if !letters && !numbers {
				end = math.MaxInt32
			} else {
				end = 'z' + 1
				start = ' '
			}
		}
	} else {
		if end <= start {
			err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) must be greater than start (%v)", end, start)
			return "", err
		}
		if chars != nil && end > len(chars) {
			err := fmt.Errorf("randomstringutils illegal argument: Parameter end (%v) cannot be greater than len(chars) (%v)", end, len(chars))
			return "", err
		}
	}
	buffer := make([]rune, count)
	gap := end - start
	for count != 0 {
		count--
		var ch rune
		if chars == nil {
			ch = rune(getCryptoRandomInt(gap) + int64(start))
		} else {
			ch = chars[getCryptoRandomInt(gap) + int64(start)]
		}
		if letters && unicode.IsLetter(ch) || numbers && unicode.IsDigit(ch) || !letters && !numbers {
			if ch >= 56320 && ch <= 57343 {  
				if count == 0 {
					count++
				} else {
					buffer[count] = ch
					count--
					buffer[count] = rune(55296 + getCryptoRandomInt(128))
				}
			} else if ch >= 55296 && ch <= 56191 {  
				if count == 0 {
					count++
				} else {
					buffer[count] = rune(56320 + getCryptoRandomInt(128))
					count--
					buffer[count] = ch
				}
			} else if ch >= 56192 && ch <= 56319 {
				count++
			} else {
				buffer[count] = ch
			}
		} else {
			count++
		}
	}
	return string(buffer), nil
}
/*
CryptoRandom creates a random string based on a variety of options, using using golang's crypto/rand source of randomness.
If the parameters start and end are both 0, start and end are set to ' ' and 'z', the ASCII printable characters, will be used,
unless letters and numbers are both false, in which case, start and end are set to 0 and math.MaxInt32, respectively.
If chars is not nil, characters stored in chars that are between start and end are chosen.

Parameters:
count - the length of random string to create
start - the position in set of chars (ASCII/Unicode int) to start at
end - the position in set of chars (ASCII/Unicode int) to end before
letters - if true, generated string may include alphabetic characters
numbers - if true, generated string may include numeric characters
chars - the set of chars to choose randoms from. If nil, then it will use the set of all chars.

Returns:
string - the random string
error - an error stemming from invalid parameters: if count < 0; or the provided chars array is empty; or end <= start; or end > len(chars)
package goutils
import (
	"crypto/rand"
	"fmt"
	"math"
	"math/big"
	"regexp"
	"unicode"
)
func CryptoRandomNonAlphaNumeric(count int) (string, error) {
	return CryptoRandomAlphaNumericCustom(count, false, false)
}
func CryptoRandomAscii(count int) (string, error) {
	return CryptoRandom(count, 32, 127, false, false)
}
func CryptoRandomNumeric(count int) (string, error) {
	return CryptoRandom(count, 0, 0, false, true)
}
func CryptoRandomAlphabetic(count int) (string, error) {
	return CryptoRandom(count, 0, 0, true, false)
}
func CryptoRandomAlphaNumeric(count int) (string, error) {
	if count == 0 {
		return "", nil
	}
	RandomString, err := CryptoRandom(count, 0, 0, true, true)
	if err != nil {
		return "", fmt.Errorf("Error: %s", err)
	}
	match, err := regexp.MatchString("([0-9]+)", RandomString)
	if err != nil {
		panic(err)
	}
	if !match {
		position := getCryptoRandomInt(count)
		RandomString = RandomString[:position] + string('0' + getCryptoRandomInt(10)) + RandomString[position + 1:]
		return RandomString, err
	}
	return RandomString, err
}
func CryptoRandomAlphaNumericCustom(count int, letters bool, numbers bool) (string, error) {
	return CryptoRandom(count, 0, 0, letters, numbers)
}