人的血液7年会全部替换一遍,鱼的记忆只有7秒。
因为工作要用到shell自动部署一个项目,所以今天我们先来研究一下shell的基础命令。#!/bin/bash # 上面这个shell脚本的头,每门语言都有自己的头字符串echo "hello" echo "hi" # 变量 num="我是变量" echo $num num1=10 num2=50 #env env是读取环境变量 # 读取进程 echo "进程号:$0" echo "进程号:$$" # ``这个符号执行变量 echo `date` # 转义字符 加上-e才行 echo -e "你好啊\n成都"判断和if条件语句# 判断 test $num1 -eq $num2 echo "相等:$?" # 条件判断 if [ $num1 = 10 ]; then echo "这是等于10" else echo "默认" fi文件夹和文件基础创建# 创建文件夹,文件系列 dirName="aaa" if [ -e $dirName ]; then echo "文件夹存在,即将进入文件夹" cd $dirName echo "创建一个文件名字叫 a.txt" touch a.txt else echo "文件夹不存在,创建该文件夹" mkdir $dirName echo "进入文件夹,然后创建文件a.txt" cd $dirName touch a.txt fi用户交互# 读取键盘输入的内容,用户交互 read -p "请输入文件夹的名字:" dirFileName if [ -e $dirFileName ]; then echo "存在该文件夹" else mkdir $dirFileName fi # 命令选择 read -p "请输入y创建文件夹,n直接退出:" yes if [ $yes = "y" ]; then mkdir haaha elif [ $yes = "n" ]; then echo "退出了" ficase语句# case语句 read -p "请输入yes/no:" choice case $choice in yes | y* | Y*) echo "输入了yes" ;; no | n* | N*) echo "输入了no" ;; *) echo "输入了其他" ;; esacfor循环# for循环 declare -i sum=0 declare -i i=0 for (( i=0; i<=100; i++ )) do sum=$sum+$i; done echo "sum=$sum" for i in 1 2 3 4 5 do sum=$sum+$i; done echo "sum=$sum" # 扫描文件 for fileName in `ls` do if [ -d $fileName ]; then echo "$fileName是文件夹" elif [ -f $fileName ]; then echo "$fileName是文件" fi done函数# 函数 function getMax() { if [ $1 -gt $2 ]; then return $1 else return $2 fi } read -p "请输入数值1:" data1 read -p "请输入数值2:" data2 # 函数调用 getMax $data1 $data2 echo "$data1和$data2的最大值为:$?"
查看详情区别:RSA加密:RSA密码体制是一种公钥密码体制,加密算法公开,以分配的密钥作为加密解密的关键。RSA签名:签名就是在这份资料后面增加一段强而有力的证明,以此证明这段信息的发布者和这段信息的有效性完整性。在使用RSA进行通讯的时候,一般是两者结合,即:加密>签名>解密>验签公钥加密、私钥解密、私钥签名、公钥验签。加密是可逆的,而签名是不可逆的我们可以对一份资料用公钥加密,再用私钥解密,但我们对这份资料进行签名则是不可逆的,因为哈希本身是不可逆的。加密和签名都涉及到了使用公钥加密,前者加密了信息,后者加密了信息的hash加密和签名都是为了安全性考虑,但略有不同。加密是为了防止信息被泄露,而签名是为了防止信息被篡改。为什么签名是对信息hash之后加密,而不是加密一些特定的字符?这是因为防止中间人尝试向私钥拥有者反复发送一些特定的字符,得到加密后的信息,达到破解或者伪造之类的目的。所以用私钥随便加密信息是不安全的。RSA的签名与加密一般用在需要非常安全的环境下,例如支付总结:签名的本质其实就是加密,但是由于签名无需还原成明文,因此可以在加密前进行哈希处理。所以签名其实就是哈希+加密,而验签就是哈希+解密+比较。签名过程:对明文做哈希,拼接头信息,用私钥进行加密,得到签名。验签过程:用公钥解密签名,然后去除头信息,对明文做哈希,比较2段哈希值是否相同,相同则验签成功。
查看详情(从 0-1 搭建你的Gin框架后台系统)go版本>=1.11一、什么是module?go中包管理工具二、使用module和不使用的区别使用环境变量中的GO111MODULE控制是否使用mod1.开启mod:go env -w GO111MODULE=on,会将包下载到gopath下的pkg下的mod文件夹中2.关闭mod:go env -w GO111MODULE=off,会将包下载到gopath下的src下3.go env GO111MODULE=auto,只有当当前目录在GOPATH/src目录之外而且当前目录包含go.mod文件或者其子目录包含go.mod文件才会启用。项目可以不用建在src下了,任何非中文路径下都可以,建议有个统一的代码路径三、go.mod文件的语法介绍go help go.mod 查看帮助示例:module my/thing go 1.13.4 require ( new/thing v2.3.4 old/thing v1.2.3 ) 1.module:指明根目录2.go 后面跟版本号是指定go的版本2.require是个动作指令,对依赖包起作用,比如require(依赖),还有exclude(排除),replace(替代),相同动作的可以放在一个动词+括号组成的结构中,如下:require ( new/thing v2.3.4 old/thing v1.2.3 ) require new/thing v2.3.4 require old/thing v1.2.3 // 排除 exclude old/thing v1.2.3 // 替换,使用箭头后的替换前面的 replace bad/thing v1.4.5 => good/thing v1.4.5 注意:exclude和replace仅适用于主的go.mod文件中,其他的依赖中会被忽略、可以使用replace替换无法获取的库,3.注释:使用//,没有/* xxx */这种块注释四、go mod 命令go mod help 查看帮助download 下载模块到本地缓存,go env中的GOCACHE路径,可以通过go clean -cache清空缓存 多个项目可以共享缓存的包 edit 在工具或脚本中编辑go.mod文件 graph 打印模块需求图 init 在当前目录下初始化新的模块 go mod init 【项目名】 默认使用当前路径的项目名称 tidy 添加缺失的模块以及移除无用的模块,生成go.sum文件 vendor 会自动下载项目中依赖的包到项目根目录下的vendor文件夹下,并写入go.mod文件,同时生成 modules.txt文件 go mod vender -v verify 检查当前模块的依赖是否全部下载下来,是否下载下来被修改过 why 解释为什么需要包或模块 注意:-v参数可以查看执行的详细信息 已经完成的项目可以这样操作来使用mod项目路径下执行go mod init然后再执行go mod vendor(或者直接运行项目)项目中可以是这样的执行顺序:init初始化 --> tidy 增删模块--> verify 校验模块-->vendor注意:项目中引入该项目下的任何路径都要是绝对路径,也就是以改项目名开头的路径使用mod的步骤:1.开启mod:go111module=on2.进入项目,执行go mod init (在项目根目录生成go.mod文件)3.启动项目(go.mod添加依赖的包)
查看详情(从 0-1 搭建你的Gin框架后台系统)我们先新建一个文件,gin_demo,然后初始化一个go项目,我们用go mod来管理包,之后我们讲一下什么是modgo mod init gin_demo接下来新建main.go文件,引入Gin,开始第一个项目package main import "github.com/gin-gonic/gin" func main() { // g:=gin.New() g := gin.Default() g.GET("/", func(c *gin.Context) { c.String(200, "hello world") }) g.Run(":9000") }运行项目:go run main我们的第一个Gin项目就可以了。运行原理一、router:=gin.Default()初始化一个引擎,是gin.New()的升级二、router.GET1.RESTFUL风格的请求方法(method)2.有两个参数:relativePath:路由,string类型HandlerFunc:执行的函数3.可以使用router.Handle代替,多了个的method参数(字符串),method参数必须是大写的,如:GET三、执行的函数1.必须有个参数是gin.Context指针类型的注意:context是gin的一个重要组成部分。用来在中间层传递数据流。2.函数是个参数,不能调用四、router.Run启动http监听,有个address参数,字符串类型的,可以指定host和port注意:addr的host和port是用冒号分隔的只指定port,port前面必须要有冒号指定了host和port,host和port中间有冒号不能只指定hostg.Run(":9000")
查看详情(从 0-1 搭建你的Gin框架后台系统)一、gin框架介绍Gin 是一个用 Go (Golang) 编写的 web 框架。它是一个类似于 martini 但拥有更好性能的 API 框架,由于 httprouter,速度提高了近 40 倍,简单易用,是一个轻量级框架。如果你是性能和高效的追求者,你会爱上 Gin。二、为什么选择gin1.运行响应非常快2.快速开发3.文档齐全4.社区活跃三、特性1.快速:基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。2.支持中间件:传入的 HTTP 请求可以由一系列中间件和最终操作来处理。 例如:Logger,Authorization,GZIP,最终操作 DB。3.Crash 处理:Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!4.JSON 验证:Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。5.路由组:更好地组织路由。是否需要授权,不同的 API 版本…… 此外,这些组可以无限制地嵌套而不会降低性能。6.错误管理:Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。7.内置渲染:Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。8.可扩展性:新建一个中间件非常简单gin环境搭建注意:go1.9版本以上,很快将不再支持go1.7或go1.8。一、go环境安装1.go安装下载地址: https://go.dev/dl/这里选择你需要下载的版本,现在最新版是1.20.5,可以自己选择需要的版本。windows,和linux的安装方法稍有差异,不过大同小异,网上有很多方法,不过多介绍,可以多参考网上。这里我们直接安装windows版本(go1.19.4)。然后,我们安装windows软件一样,傻瓜式操作,直接下一步,下一步到底。2.环境配置:变量名:GOPATH 变量值:E:\go\workspace 你的工作路径变量名:GOROOT 变量值:E:\go\install go的安装路径变量名:Path 增加值:%GOROOT%\bin;%GOPATH%\bin;注意:删除自动添加的gopath和goroot注意添加完GOPATH,GOROOT两个变量值,还需要添加他们下面的bin执行目录。3.检查配置是否成功go env 查看GOPATH和GOROOT是否正确然后就可以看到安装的目录和版本是否正确,当显示下面截图,我们就安装成功了。二、工程管理:工作目录下新建三个文件夹1.src:用于以代码包的形式组织并保存go源码文件,2.pkg:用于存放经由go install命令构建的安装后的代码包,不需要手动创建3.bin:与pkg目录类似,在通过go install命令完成安装后,保存由go命令源码间生成的可执行文件三、安装gingin的安装就很简单了,直接命令拉取。go get -u github.com/gin-gonic/gin五、安装编辑工具(goland,vscode等都可以,看自己喜欢)第一节我们就到这里结束了,接下来我们就开始gin框架吧。hello world
查看详情JS生成二维码,其实很容易。下面我们来测试一下,一些简单的二维码就用JS生成。我们用一个生成二维码的库: https://github.com/SumiMakito/Awesome-qr.js 在网上翻了一些资料,这个库是没有什么缺点的,当然也可以尝试用其他生成二维码的库。html引入Awesome-qr库:<script src='./qr/dist/awesome-qr.js' type="text/javascript"></script> <script src="http://www.alingfeng.cn/js/jquery.min.js"></script>生成二维码:<img id="qrcodeimg"/ > <script> var creatqrcode = function (text, logo, background) { // 二维码生成参数 var text = "http://www.alingfeng.cn"; var size = 200; var colorDark = "#000000"; var margin = 9 var background = background || "#ffffff"; var logo = logo || ""; $("#qrcodeimg").css({width:size+"px",height:size+"px"}) new AwesomeQR.AwesomeQR({ text: text, // 内容 size: size, // 二维码大小 margin: margin, // 二维码白边大小 colorDark:colorDark, // 二维码颜色 colorLight: "rgba(159,255,255,0)", // 二维码背景颜色 logoImage : logo, // 二维码中间logo logoScale : 0.3, // 二维码中间logo大小 logoCornerRadius : 0, // 二维码中间logo圆角 }).draw() .then((dataURL) => { $("#qrcodeimg").attr("src", dataURL) }) .catch((err) => { console.error(err); }); } $(function(){ // 初始化生成二维码 creatqrcode("http://www.alingfeng.cn") }) </script>然后生成二维码试试:
查看详情前两天在做项目的时候,用到了排序,在网上查阅了一些资料做了部分对比,所以对常用的排序做了一些对比。当然不是全部,例如归并排序,二叉树之类的。等以后有时间可以了解一下。下面我们就了解一下这些排序;首先,我们先生成100位随机数字,然后对这一组数字进行排序。package main import ( "fmt" "math" mathRand "math/rand" "time" ) func main() { // 生成随机数 mathRand.Seed(time.Now().UnixNano()) var arr [100]int // 不重复生成 for i := 0; i < 100; i++ { arr[i] = mathRand.Intn(100) loop: for k := 0; k < i; k++ { if arr[k] == arr[i] { arr[i] = mathRand.Intn(100) goto loop } } } //打印随机数据 fmt.Println("生成的随机数切片:\n", arr) }1、冒泡排序// 冒泡排序方法 func mpArr(data [100]int) [100]int { var arrx int for i := 0; i < len(data)-1; i++ { for j := 0; j < len(data)-i-1; j++ { arrx++ if data[j] > data[j+1] { //交换 data[j], data[j+1] = data[j+1], data[j] } } } fmt.Println("冒泡排序排序次数", arrx) return data } mpArr := mpArr(arr) fmt.Println("冒泡排序之后的切片", mpArr)我们可以看到冒泡排序是比较稳定的。2、插入排序// 插入排序 func insertSort(data [100]int) [100]int { var j int var pxNum int for i := 1; i < len(data); i++ { temp := data[i] for j = i; j > 0 && temp < data[j-1]; j-- { data[j] = data[j-1] pxNum++ } data[j] = temp } fmt.Println("改进版插入排序次数:", pxNum) return data } // 改进版插入排序 func InsertionSort2(arr [100]int) [100]int { n := len(arr) var pxNum int for i := 1; i < n; i++ { // 无序区 tmp := arr[i] left, right := 0, i-1 for left <= right { pxNum++ mid := (left + right) / 2 if arr[mid] > tmp { right = mid - 1 } else { left = mid + 1 } } j := i - 1 for ; j >= left; j-- { // 有序区 arr[j+1] = arr[j] pxNum++ } arr[left] = tmp } fmt.Println("插入排序次数:", pxNum) return arr } // 使用插入排序 cr2Arr := InsertionSort2(arr) fmt.Println("插入排序之后的切片", cr2Arr) // 使用改进版插入排序 crArr := insertSort(arr) fmt.Println("改进版插入排序之后的切片", crArr)我们可以看到插入排序也是比较稳定的。3、选择排序// 选择排序 func SelectionSort(arr [100]int) [100]int { var pxNum int n := len(arr) for i := 0; i < n-1; i++ { minNumIndex := i // 无序区第一个 for j := i + 1; j < n; j++ { if arr[j] < arr[minNumIndex] { minNumIndex = j pxNum++ } } arr[i], arr[minNumIndex] = arr[minNumIndex], arr[i] } fmt.Println("选择排序次数:", pxNum) return arr } // 使用选择排序 xzArr := SelectionSort(arr) fmt.Println("选择排序之后的切片", xzArr)由此可以看出,选择排序是不稳定的4、希尔排序// 希尔排序 func shellSort(data [100]int) [100]int { var j int var pxNum int for h := len(data) / 2; h > 0; h /= 2 { //外层循环控制步长 for i := h; i < len(data); i++ { //内层循环是对步长个子切片做插入排序 temp := data[i] for j = i; j >= h && temp < data[j-h]; j -= h { data[j] = data[j-h] pxNum++ } data[j] = temp } } fmt.Println("希尔排序次数:", pxNum) return data } xrArr := shellSort(arr) fmt.Println("希尔排序之后的切片", xrArr)希尔排序也是不稳定的5、堆排序// 堆排序 func heapSort(data [100]int) [100]int { m := len(data) var pxNum int s := m / 2 for i := s; i >= 0; i-- { heap(data, i, m-1) } for i := m - 1; i > 0; i-- { data[i], data[0] = data[0], data[i] heap(data, 0, i-1) pxNum++ } fmt.Println("堆排序次数:", pxNum) return data } dArr := heapSort(arr) fmt.Println("堆排序之后的切片", dArr)堆排序也是不稳定的6、基数排序// 基数排序 func RadixSort(arr [100]int) [100]int { var pxNum int maxn := maxBitNum(arr) // arr最大位数 dev := 1 // 除数,保证商最后一位是我们想要的 mod := 10 // 模,取商的最后一位 for i := 0; i < maxn; i++ { // 进行maxn次排序 bucket := make([][]int, 10) // 定义10个空桶 result := make([]int, 0) // 存储中间结果 for _, v := range arr { n := v / dev % mod // 取出对应位的值,放入对应桶中 bucket[n] = append(bucket[n], v) pxNum++ } dev *= 10 // 按顺序存入中间切片 for j := 0; j < 10; j++ { result = append(result, bucket[j]...) pxNum++ } // 转存到原切片(结果) for k := range arr { arr[k] = result[k] pxNum++ } } fmt.Println("基数排序次数:", pxNum) return arr } zsArr := RadixSort(arr) fmt.Println("基数排序之后的切片", zsArr)基数排序是稳定的。7、快速排序// 快速排序 func QuickSort(left int, right int, array *[100]int) { l := left r := right // pivot 是中轴, 支点 pivot := array[(left+right)/2] temp := 0 // for 循环的目标是将比 pivot 小的数放到左边,比 pivot 大的数放到右边 for l < r { // 从 pivot 的左边找到大于等于pivot的值 for array[l] < pivot { l++ } // 从 pivot 的右边边找到小于等于pivot的值 for array[r] > pivot { r-- } // 1 >= r 表明本次分解任务完成, break if l >= r { break } // 交换 temp = array[l] array[l] = array[r] array[r] = temp // 优化 if array[l] == pivot { r-- } if array[r] == pivot { l++ } } // 如果 1== r, 再移动下 if l == r { l++ r-- } // 向左递归 if left < r { QuickSort(left, r, array) } // 向右递归 if right > l { QuickSort(l, right, array) } } ksArr := arr QuickSort(0, len(ksArr)-1, &ksArr) fmt.Println("快速排序之后的切片", ksArr)快排也是不稳定的。8、计数排序// 计数排序 func CountingSort(arr [100]int) [100]int { var pxNum int length := len(arr) maxValue := getMaxValue(arr) bucketLen := maxValue + 1 bucket := make([]int, bucketLen) sortedIndex := 0 // 统计每个元素出现的个数 for i := 0; i < length; i++ { bucket[arr[i]] += 1 pxNum++ } // 按照统计结果写入arr for j := 0; j < length; j++ { for bucket[j] > 0 { pxNum++ arr[sortedIndex] = j // bucket[j]的值是统计结果,后面会变化,j是真正值 sortedIndex++ bucket[j]-- } } fmt.Println("计数排序次数:", pxNum) return arr } jsArr := CountingSort(arr) fmt.Println("计数排序之后的切片", jsArr)计数排序也是稳定的 稳定的排序算法有:冒泡排序、插入排序、计数排序、基数排序。 不稳定的排序算法有:选择排序、希尔排序、快速排序、堆排序。 当然每个排序方法只有最适合的场景,不能单从稳定性考虑,也要从性能上考虑,不能一概而论。
查看详情《千字文》为南朝周兴嗣所编,它的撰作,相传还有一段故事;原来是当年梁武帝令殷铁石在王羲之书写的碑文中拓下不重复的一千个字,供皇子们学书用的。但由于字字孤立,互不联属,所以他又召来周兴嗣嘱道:“卿有才思,为我韵之。”周兴嗣只用了一个晚上就编好进呈武帝。这便是传至今日的《千字文》。周兴嗣的《千字文》精思巧构,知识丰瞻,音韵谐美,宜蒙童记诵,故成为千百年蒙学教科书。天地玄黄,宇宙洪荒。日月盈昃,辰宿列张。寒来暑往,秋收冬藏。闰余成岁,律吕调阳。云腾致雨,露结为霜。金生丽水,玉出昆冈。剑号巨阙,珠称夜光。果珍李柰,菜重芥姜。海咸河淡,鳞潜羽翔。龙师火帝,鸟官人皇。始制文字,乃服衣裳。推位让国,有虞陶唐。吊民伐罪,周发殷汤。坐朝问道,垂拱平章。爱育黎首,臣伏戎羌。遐迩一体,率宾归王。鸣凤在竹,白驹食场。化被草木,赖及万方。盖此身发,四大五常。恭惟鞠养,岂敢毁伤。女慕贞洁,男效才良。知过必改,得能莫忘。罔谈彼短,靡恃己长。信使可覆,器欲难量。墨悲丝染,诗赞羔羊。景行维贤,克念作圣。德建名立,形端表正。空谷传声,虚堂习听。祸因恶积,福缘善庆。尺璧非宝,寸阴是竞。资父事君,曰严与敬。孝当竭力,忠则尽命。临深履薄,夙兴温凊。似兰斯馨,如松之盛。川流不息,渊澄取映。容止若思,言辞安定。笃初诚美,慎终宜令。荣业所基,籍甚无竟。学优登仕,摄职从政。存以甘棠,去而益咏。乐殊贵贱,礼别尊卑。上和下睦,夫唱妇随。外受傅训,入奉母仪。诸姑伯叔,犹子比儿。孔怀兄弟,同气连枝。交友投分,切磨箴规。仁慈隐恻,造次弗离。节义廉退,颠沛匪亏。性静情逸,心动神疲。守真志满,逐物意移。坚持雅操,好爵自縻。都邑华夏,东西二京。背邙面洛,浮渭据泾。宫殿盘郁,楼观飞惊。图写禽兽,画彩仙灵。丙舍旁启,甲帐对楹。肆筵设席,鼓瑟吹笙。升阶纳陛,弁转疑星。右通广内,左达承明。既集坟典,亦聚群英。杜稿钟隶,漆书壁经。府罗将相,路侠槐卿。户封八县,家给千兵。高冠陪辇,驱毂振缨。世禄侈富,车驾肥轻。策功茂实,勒碑刻铭。盘溪伊尹,佐时阿衡。奄宅曲阜,微旦孰营。桓公匡合,济弱扶倾。绮回汉惠,说感武丁。俊义密勿,多士实宁。晋楚更霸,赵魏困横。假途灭虢,践土会盟。何遵约法,韩弊烦刑。起翦颇牧,用军最精。宣威沙漠,驰誉丹青。九州禹迹,百郡秦并。岳宗泰岱,禅主云亭。雁门紫塞,鸡田赤诚。昆池碣石,钜野洞庭。旷远绵邈,岩岫杳冥。治本于农,务兹稼穑。俶载南亩,我艺黍稷。税熟贡新,劝赏黜陟。孟轲敦素,史鱼秉直。庶几中庸,劳谦谨敕。聆音察理,鉴貌辨色。贻厥嘉猷,勉其祗植。省躬讥诫,宠增抗极。殆辱近耻,林皋幸即。两疏见机,解组谁逼。索居闲处,沉默寂寥。求古寻论,散虑逍遥。欣奏累遣,戚谢欢招。渠荷的历,园莽抽条。枇杷晚翠,梧桐蚤凋。陈根委翳,落叶飘摇。游鹍独运,凌摩绛霄。耽读玩市,寓目囊箱。易輶攸畏,属耳垣墙。具膳餐饭,适口充肠。饱饫烹宰,饥厌糟糠。亲戚故旧,老少异粮。妾御绩纺,侍巾帷房。纨扇圆洁,银烛炜煌。昼眠夕寐,蓝笋象床。弦歌酒宴,接杯举殇。矫手顿足,悦豫且康。嫡后嗣续,祭祀烝尝。稽颡再拜,悚惧恐惶。笺牒简要,顾答审详。骸垢想浴,执热愿凉。驴骡犊特,骇跃超骧。诛斩贼盗,捕获叛亡。布射僚丸,嵇琴阮箫。恬笔伦纸,钧巧任钓。释纷利俗,并皆佳妙。毛施淑姿,工颦妍笑。年矢每催,曦晖朗曜。璇玑悬斡,晦魄环照。指薪修祜,永绥吉劭。矩步引领,俯仰廊庙。束带矜庄,徘徊瞻眺。孤陋寡闻,愚蒙等诮。谓语助者,焉哉乎也。
查看详情2023年百家姓全文:赵钱孙李 周吴郑王 冯陈褚卫 蒋沈韩杨朱秦尤许 何吕施张 孔曹严华 金魏陶姜戚谢邹喻 柏水窦章 云苏潘葛 奚范彭郎鲁韦昌马 苗凤花方 俞任袁柳 酆鲍史唐费廉岑薛 雷贺倪汤 滕殷罗毕 郝邬安常乐于时傅 皮卞齐康 伍余元卜 顾孟平黄和穆萧尹 姚邵湛汪 祁毛禹狄 米贝明臧计伏成戴 谈宋茅庞 熊纪舒屈 项祝董梁杜阮蓝闵 席季麻强 贾路娄危 江童颜郭梅盛林刁 钟徐邱骆 高夏蔡田 樊胡凌霍虞万支柯 昝管卢莫 经房裘缪 干解应宗丁宣贲邓 郁单杭洪 包诸左石 崔吉钮龚程嵇邢滑 裴陆荣翁 荀羊於惠 甄曲家封芮羿储靳 汲邴糜松井段富巫 乌焦巴弓牧隗山谷 车侯宓蓬全郗班仰 秋仲伊宫宁仇栾暴 甘钭厉戎 祖武符刘 景詹束龙叶幸司韶 郜黎蓟薄 印宿白怀 蒲邰从鄂索咸籍赖 卓蔺屠蒙 池乔阴郁 胥能苍双闻莘党翟 谭贡劳逄 姬申扶堵 冉宰郦雍却璩桑桂 濮牛寿通 边扈燕冀 郏浦尚农温别庄晏 柴瞿阎充 慕连茹习 宦艾鱼容向古易慎 戈廖庾终 暨居衡步 都耿满弘匡国文寇 广禄阙东 欧殳沃利 蔚越夔隆师巩厍聂 晁勾敖融 冷訾辛阚 那简饶空曾毋沙乜 养鞠须丰 巢关蒯相 查后荆红游竺权逯 盖益桓公 万俟司马 上官欧阳(复姓)夏侯诸葛 闻人东方(复姓)赫连皇甫 尉迟公羊(复姓)澹台公冶 宗政濮阳(复姓) 淳于单于 太叔申屠(复姓)公孙仲孙 轩辕令狐(复姓) 钟离宇文 长孙慕容(复姓)鲜于闾丘 司徒司空(复姓) 亓官司寇 仉督子车(复姓)颛孙端木 巫马公西(复姓) 漆雕乐正 壤驷公良(复姓)拓跋夹谷 宰父谷梁(复姓) 晋楚闫法 汝鄢涂钦段干百里 东郭南门(复姓) 呼延 归 海 羊舌 微生(有复姓)岳帅缑亢 况后有琴 梁丘左丘 东门西门(复姓)商牟佘佴 伯 赏 南宫(有复姓)墨哈谯笪 年爱阳佟第五 言 福(有复姓)《百家姓》终 中国人口最多姓氏前十排名: 1、王姓-占全中国汉族人口的 7.94%=101,300,000人。 2、张姓 -占全中国汉族人口的 7.41%=100,900,000人。 3、李姓 -占全中国汉族人口的 7.07%=95,800,000人。 4、刘姓 -占全中国汉族人口的' 5.38%=70,600,000人。 5、陈姓 -占全中国汉族人口的 4.53%=54,400,000人。 6、杨姓 -占全中国汉族人口的 3.08%=41,000,000人。 7、黄姓 -占全中国汉族人口的 2.29%=29,500,000人。 8、周姓 -占全中国汉族人口的 2.23%=26,800,000人。 9、胡姓 -占全中国汉族人口的 2.12%=25,400,000人。 10、赵姓-占全中国汉族人口的 2.05%=24,600,000人。 中国人口最多的前100名姓氏:前十名总人口约为5.5亿人。 11吴 12徐 13宋 14林 15朱 16孙17高 18曹 19郭 20马 21罗 22何23梁 24谢 25韩 26郑 27于 28唐 29董 30夏 31傅 32冯 33袁 34薛 35许 36姚 37彭 38曾 39汪 40江 41苏 42卢 43叶 44余 45肖 46魏47邓48谭 49阎 50丁 51潘 52杜 53戴 54毛 55钟 56廖57田 58任59姜 60范 61方 62贾 63蔡 64程 65沈 66邹 67熊 68金69陆 70郝 71孔 72白 73崔 74康 75吕 76邱 77秦 78蒋79石 80史 81顾 82侯 83邵 84孟 85龙 86 万 87段 88莫 89钱 90汤 91尹 92黎 93易 94常 95武 96乔 97贺 98赖 99龚 100文
查看详情代码:package main import ( "bytes" "encoding/base64" "fmt" "github.com/nfnt/resize" "image" _ "image/jpeg" "image/png" "github.com/skip2/go-qrcode" "golang.org/x/image/draw" "os" ) // CreateQrCodeBs64WithLogo 带logo的二维码图片生成 content-二维码内容 size-像素单位 logoPath-logo文件路径 func CreateQrCodeBs64WithLogo(content, logoPath, outPath string, size int) (data string, err error) { code, err := qrcode.New(content, qrcode.High) if err != nil { return } //code.DisableBorder = true //设置文件大小并创建画板 qrcodeImg := code.Image(size) outImg := image.NewRGBA(qrcodeImg.Bounds()) //读取logo文件 logoFile, err := os.Open(logoPath) if err != nil { return } logoImg, _, _ := image.Decode(logoFile) logoImg = resize.Resize(uint(size/10), 0, logoImg, resize.Lanczos3) // 添加边框 // 图片到边框距离 pic2FramePadding := logoImg.Bounds().Dx() / 10 // 新建一个边框图层 transparentImg := image.NewRGBA(image.Rect(0, 0, logoImg.Bounds().Dx()+pic2FramePadding, logoImg.Bounds().Dy()+pic2FramePadding)) // 图层颜色设为白色 draw.Draw(transparentImg, transparentImg.Bounds(), image.White, image.Point{}, draw.Over) // 将缩略图放到透明图层上 draw.Draw(transparentImg, image.Rect(pic2FramePadding/2, pic2FramePadding/2, transparentImg.Bounds().Dx(), transparentImg.Bounds().Dy()), logoImg, image.Point{}, draw.Over) //logo和二维码拼接 draw.Draw(outImg, outImg.Bounds(), qrcodeImg, image.Pt(0, 0), draw.Over) offset := image.Pt((outImg.Bounds().Max.X-transparentImg.Bounds().Max.X)/2, (outImg.Bounds().Max.Y-transparentImg.Bounds().Max.Y)/2) draw.Draw(outImg, outImg.Bounds().Add(offset), transparentImg, image.Pt(0, 0), draw.Over) buf := new(bytes.Buffer) _ = png.Encode(buf, outImg) // 写入文件 f, _ := os.Create(outPath) _ = png.Encode(f, outImg) res := base64.StdEncoding.EncodeToString(buf.Bytes()) return res, nil } func main() { s, err := CreateQrCodeBs64WithLogo("http://www.alingfeng.cn/", "logo.png", "qr.png", 512) if err != nil { fmt.Println(err) return } fmt.Println(s) } 结果:
查看详情人的血液7年会全部替换一遍,鱼的记忆只有7秒。