package pwgen func runeFor(alphabet []rune, prng Int32n) rune { return alphabet[prng.Int31n(int32(len(alphabet)))] } func alphabet(start, end rune) (result []rune) { length := end - start + 1 result = make([]rune, length) for i := int32(0); i < length; i++ { result[i] = start + i } return result } func merge[T any](slices ...[]T) []T { var totalLength int for i := range slices { totalLength += len(slices[i]) } result := make([]T, totalLength) var offset int for i := range slices { copy(result[offset:], slices[i]) offset += len(slices[i]) } return result } func shuffle[T comparable](in []T, prng Int32n) (result []T) { if !canShuffle(in) { return in } for { result = make([]T, 0, len(in)) temp := make([]T, len(in)) copy(temp, in) for len(temp) > 0 { var i int32 for { i = prng.Int31n(int32(len(temp))) if i != int32(len(result)) { break } } result = append(result, temp[i]) copy(temp[i:], temp[i+1:]) temp = temp[:len(temp)-1] } if !sequenceEqual(in, result) { return result } } } func canShuffle[T comparable](in []T) bool { if len(in) < 2 { return false } uniq := make(map[T]bool) for _, r := range in { uniq[r] = true if len(uniq) > 1 { return true } } return false } func sequenceEqual[T comparable](first, second []T) bool { if len(first) != len(second) { return false } for i := range first { if first[i] != second[i] { return false } } return true }