Golang如何构造最佳随机密码详解

为了保护系统或数据安全,我们需要最佳随机密码。这里使用unix系统定义的文件设备/dev/random,从中获取随机数生成器的种子。

需求说明

定义程序goodPass.go,程序需要一个可选命令行参数,指定生成密码的长度,缺省长度为10. 另外生成密码的ASCII从!z,对应ascii码为33到122。

程序第一部分是导入相应的包:

package main

import (
	"encoding/binary"
	"fmt"
	"math/rand"
	"os"
	"path/filepath"
	"strconv"
)

var MAX = 90
var MIN = 0

// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n)
// from the default Source.
// It panics if n <= 0.
func random(min, max int) int {
	return rand.Intn(max-min) + min
}

这里radmon函数生成一定范围内的,Intn()结果不包括末端数值。下面实现main函数,处理命令行参数,并从随机文件设备中获取随机种子:

func main() {
	var LENGTH int64 = 10
	if len(os.Args) != 2 {
		fmt.Printf("usage: %s length\n", filepath.Base(os.Args[0]))
		//os.Exit(1)
		fmt.Printf("Default length is %d\n", LENGTH)
	} else {
		LENGTH, _ = strconv.ParseInt(os.Args[1], 10, 64)
	}

	f, _ := os.Open("/dev/random")
	var seed int64

	_ = binary.Read(f, binary.LittleEndian, &seed)
	_ = f.Close()

	rand.Seed(seed)
	fmt.Println("Seed:", seed)

    GenPass(LENGTH)
}

首先处理命令行参数,如果没有指定长度,则取默认值10,否则解析命令行参数。

然后打开/dev/random 设备进行读取,这里使用binary.Read是需要指定字节顺序(binary.LittleEndian),这是为了构建int64类型,而不是获得一串字节。这里为了展示如何从二进制文件读内容至Go类型。

binary.Read(f, binary.LittleEndian, &seed) 函数的源码注释为:

// Read reads structured binary data from r into data.
// Data must be a pointer to a fixed-size value or a slice of fixed-size values.
// Bytes read from r are decoded using the specified byte order and written to successive fields of the data.
// When decoding boolean values, a zero byte is decoded as false, and any other non-zero byte is decoded as true.

最后一部分代码为:

func GenPass(LENGTH int64) {
	startChar := "!"
	var i int64
	for i = 0; i < LENGTH; i++ {
		anInt := random(MIN, MAX)
		newChar := string(startChar[0] + byte(anInt))
		if newChar == " " {
			i = i - i
			continue
		}
		fmt.Print(newChar)
	}
	fmt.Println()
}

我们看到Go处理Ascii字符有点奇怪,这是因为Go默认支持Unicode字符。因此需要转换整数值ascii字符,对应代码为:

newChar := string(startChar[0] + byte(anInt))

运行程序,生成下列输出:

$ go run goodPass.go 1
Seed: -5195038511418503382
b

$ go run goodPass.go 10
Seed: 8492864627151568776
k43Ve`+YD)

$ go run goodPass.go 50
Seed: -4276736612056007162
!=Gy+;XV>6eviuR=ST\u:Mk4Q875Y4YZiZhq&q_4Ih/]''`2:x

总结

到此这篇关于Golang如何构造最佳随机密码的文章就介绍到这了,更多相关Golang最佳随机密码内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • golang生成指定位数的随机数的方法

    1.随机数 随机数,是使用一个确定性的算法计算出来随机数序.在程序开发中经常需要产生随机数,如随机数验证码登陆.作为唯一身份标识数据等等. 2.rand库 golang中产生随机数主要有两个包,分别是"math/rand"和"crypto/rand". "math/rand"的rand包实现了伪随机数生成器. "crypto/rand"的rand包实现了用于加解密的更安全的随机数生成器. 3.生成指定位数随机数 以生成六位随机

  • golang中随机数rand的使用

    目录 1.math/rand 2.crypto/rand 1.math/rand 随机数从资源生成.包水平的函数都使用的默认的公共资源. 该资源会在程序每次运行时都产生确定的序列.如果需要每次运行产生不同的序列,应使用Seed函数进行初始化.默认资源可以安全的用于多go程并发. 关于种子seed程序启动的时候,种子的初始值是一样的,也就是说随机数是一样的,什么意思呢? package main import (    "fmt"    "math/rand" ) f

  • golang 随机数的两种方式

    golang支持两种随机数生成方式: math/rand          // 伪随机 crypto/rand        // 真随机 math/rand伪随机生成的数字是确定的,不论在什么机器.什么时间,只要执行的随机代码一样,那么生成的随机数就一样.为了尽量随机性,那么我们可以每次使用不同的seed来启动程序,就可以保证每次启动都产生新的随机数,聪明的你肯定想到了使用时间戳 func main() { fmt.Println(rand.Intn(100)) //设置随机数种子,由于种子

  • GoLang 中的随机数的示例代码

    随机数我们都知道,就是计算机通过某种算法,"随机"的生成一个数字.很多编程语言都有内置的方法来生成随机数,那么 GoLang 中是怎样一种情况呢? 伪随机数 我们都知道"随机数"在现实生活中的概念,可能你随手抛一个硬币,就可以说其结果是随机的,但是在计算机中要确定一个"随机数"真的是"随机数",那可是有标准的,不是你随随便便说是就是. 根据密码学原理,要想对一个"随机数"进行随机性检验有以下几个标准: 统计

  • 利用Golang生成整数随机数方法示例

    php随机数 生成一个给定范围的随机数,用 PHP 就太简单不过了,而且可以指定从负数到正整数的范围,如: <?php echo mt_rand(-988, 888); 这样就随机生成 -988 到 888 的随机数. 使用 Go 就要稍微麻烦一点.以下两个函数分别是生成一个最大范围内随机整数,和生成一个区间范围的随机整数: 生成一个最大范围内随机数 一定要给一个时间戳的种子,否则每次生成都是一样的值.这里就是生成 [0,100) 的随机数. func GenerateRandnum() int

  • Golang如何构造最佳随机密码详解

    为了保护系统或数据安全,我们需要最佳随机密码.这里使用unix系统定义的文件设备/dev/random,从中获取随机数生成器的种子. 需求说明 定义程序goodPass.go,程序需要一个可选命令行参数,指定生成密码的长度,缺省长度为10. 另外生成密码的ASCII从!到z,对应ascii码为33到122. 程序第一部分是导入相应的包: package main import ( "encoding/binary" "fmt" "math/rand&quo

  • 对Golang import 导入包语法详解

    package 的导入语法 写 Go 代码的时经常用到 import 这个命令用来导入包,参考如下: import( "fmt" ) 然后在代码里面可以通过如下的方式调用: fmt.Println( "我爱北京天安门" ) fmt 是 Go 的标准库,它其实是去 GOROOT 下去加载该模块,当然 Go 的 import 还支持如下两种方式来加载自己写的模块: 相对路径 import "./model" // 当前文件同一目录的 model 目录

  • golang 切片截取参数方法详解

    以 s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}为例 0. 建议:做slice截取时建议用两个参数,尤其是从底层数组进行切片操作时,因为这样在进行第一次append操作时,会给切片重新分配空间,这样减少切片对数组的影响. 1. 结论:s = s[low : high : max] 切片的三个参数的切片截取的意义为 low为截取的起始下标(含), high为窃取的结束下标(不含high),max为切片保留的原切片的最大下标(不含max):即新切片从老切片的low

  • 深入Golang中的sync.Pool详解

    我们通常用golang来构建高并发场景下的应用,但是由于golang内建的GC机制会影响应用的性能,为了减少GC,golang提供了对象重用的机制,也就是sync.Pool对象池. sync.Pool是可伸缩的,并发安全的.其大小仅受限于内存的大小,可以被看作是一个存放可重用对象的值的容器. 设计的目的是存放已经分配的但是暂时不用的对象,在需要用到的时候直接从pool中取. 任何存放区其中的值可以在任何时候被删除而不通知,在高负载下可以动态的扩容,在不活跃时对象池会收缩. sync.Pool首先

  • Golang之sync.Pool使用详解

    前言 我们通常用 Golang 来开发并构建高并发场景下的服务,但是由于 Golang 内建的GC机制多少会影响服务的性能,因此,为了减少频繁GC,Golang提供了对象重用的机制,也就是使用sync.Pool构建对象池. sync.Pool介绍 首先sync.Pool是可伸缩的临时对象池,也是并发安全的.其可伸缩的大小会受限于内存的大小,可以理解为是一个存放可重用对象的容器.sync.Pool设计的目的就是用于存放已经分配的但是暂时又不用的对象,而且在需要用到的时候,可以直接从该pool中取.

  • Golang泛型的使用方法详解

    目录 1. 泛型是什么 2. 泛型的简单使用 2.1. 泛型示例 2.2. 自定义泛型类型 2.3. 调用带泛型的函数 3. 自定义泛型类型的语法 3.1. 内置的泛型类型any和comparable 3.2. 声明一个自定义类型 3.3. 泛型中的"~"符号是什么 4. 泛型的进阶使用 4.1. 泛型与结构体 5. 泛型的限制或缺陷 5.1 无法直接和switch配合使用 1. 泛型是什么 泛型生命周期只在编译期,旨在为程序员生成代码,减少重复代码的编写 在比较两个数的大小时,没有泛

  • golang字符串本质与原理详解

    目录 一.字符串的本质 1.字符串的定义 2.字符串的长度 3.字符与符文 二.字符串的原理 1.字符串的解析 2.字符串的拼接 3.字符串的转换 总结 一.字符串的本质 1.字符串的定义 golang中的字符(character)串指的是所有8比特位字节字符串的集合,通常(非必须)是UTF-8 编码的文本. 字符串可以为空,但不能是nil. 字符串在编译时即确定了长度,值是不可变的. // go/src/builtin/builtin.go // string is the set of al

  • golang构建工具Makefile使用详解

    目录 正文 正文 可能是因为编译太简单了,golang 并没有一个官方的构建工具(类似于 java 的 maven 和 gradle之类的),但是除了编译,我们可能还需要下载依赖,运行测试,甚至像 easyjson,protobuf,thrift 这样的工具下载和代码生成,如果没有构建工具,这些工作就会非常麻烦 为了解决这个问题,之前写过一个 everything.sh 的脚本,把所有的操作都封装在这个脚本里面,只需要执行类似于 sh everything.sh dependency 的命令就可

  • Golang分布式应用之Redis示例详解

    目录 正文 分布式锁 运行测试 分布式过滤器 运行测试 分布式限流器 运行测试 其他 正文 Redis作是一个高性能的内存数据库,常被应用于分布式系统中,除了作为分布式缓存或简单的内存数据库还有一些特殊的应用场景,本文结合Golang来编写对应的中间件. 本文所有代码见github.com/qingwave/go… 分布式锁 单机系统中我们可以使用sync.Mutex来保护临界资源,在分布式系统中同样有这样的需求,当多个主机抢占同一个资源,需要加对应的“分布式锁”. 在Redis中我们可以通过s

  • Golang信号量设计实现示例详解

    目录 开篇 信号量 semaphore 扩展库实现 Acquire Release TryAcquire 总结 开篇 在我们此前的文章 Golang Mutex 原理解析 中曾提到过,Mutex 的底层结构包含了两个字段,state 和 sema: type Mutex struct { state int32 sema uint32 } state 代表互斥锁的状态,比如是否被锁定: sema 表示信号量,协程阻塞会等待该信号量,解锁的协程释放信号量从而唤醒等待信号量的协程. 这个 sema

随机推荐