緣起:
編譯下面這段代碼時(shí),在Mac上沒有什么問題,正常運(yùn)行,
點(diǎn)擊查看代碼:
package?main
import?(
?"bytes"
?"encoding/binary"
?"encoding/json"
?"fmt"
?"log"
?"math/rand"
?"net/http"
?"time"
)
func?main()?{
?http.HandleFunc("/register",?deal)?//設(shè)置訪問的路由
?fmt.Println("1111:",?2222)
?err?:=?http.ListenAndServe(":8088",?nil)?//設(shè)置監(jiān)聽的端口
?if?err?!=?nil?{
??log.Fatal("ListenAndServe:?",?err)
?}
}
func?deal(w?http.ResponseWriter,?r?*http.Request)?{
?//?Golang:?接收GET和POST參數(shù)?https://www.cnblogs.com/liuhe688/p/11063945.html
?//?根據(jù)請求body創(chuàng)建一個(gè)json解析器實(shí)例
?decoder?:=?json.NewDecoder(r.Body)
?//?用于存放參數(shù)key=value數(shù)據(jù)
?var?params?map[string]string
?//?解析參數(shù)?存入map
?decoder.Decode(¶ms)
?name?:=?params["name"]
?rand.Seed(time.Now().UnixNano())
?key?:=?crack(name)
?fmt.Println("name:",?name,?"????key:",?crack(name))
?fmt.Fprintf(w,?key)?//這個(gè)寫入到w的是輸出到客戶端的
}
const?(
?rounds????=?12
?roundKeys?=?2?*?(rounds?+?1)
)
func?crack(text?string)?string?{
?name?:=?[]byte(text)
?length?:=?len(name)?+?4
?padded?:=?((-length)?&?(8?-?1))?+?length
?bs?:=?make([]byte,?4)
?binary.BigEndian.PutUint32(bs,?uint32(len(name)))
?buff?:=?bytes.Buffer{}
?buff.Write(bs)
?buff.Write(name)
?var?ckName?int64?=?0x7a21c951691cd470
?var?ckKey?int64?=?-5408575981733630035
?ck?:=?newCkCipher(ckName)
?outBuff?:=?bytes.Buffer{}
?for?i?:=?0;?i?<?padded;?i?+=?8?{
??bf?:=?buff.Bytes()[i?:?i+8]
??buf?:=?bytes.NewBuffer(bf)
??var?nowVar?int64
??if?err?:=?binary.Read(buf,?binary.BigEndian,?&nowVar);?err?!=?nil?{
???panic(err)
??}
??dd?:=?ck.encrypt(nowVar)
??outBuff.WriteByte(byte(dd?>>?56))
??outBuff.WriteByte(byte(dd?>>?48))
??outBuff.WriteByte(byte(dd?>>?40))
??outBuff.WriteByte(byte(dd?>>?32))
??outBuff.WriteByte(byte(dd?>>?24))
??outBuff.WriteByte(byte(dd?>>?16))
??outBuff.WriteByte(byte(dd?>>?8))
??outBuff.WriteByte(byte(dd))
?}
?var?n?int32
?for?_,?b?:=?range?outBuff.Bytes()?{
??n?=?rotateLeft(n^int32(int8(b)),?0x3)
?}
?prefix?:=?n?^?0x54882f8a
?suffix?:=?rand.Int31()
?in?:=?int64(prefix)?<<?32
?s?:=?int64(suffix)
?switch?suffix?>>?16?{
?case?0x0401:
?case?0x0402:
?case?0x0403:
??in?|=?s
??break
?default:
??in?|=?0x01000000?|?(s?&?0xffffff)
??break
?}
?out?:=?newCkCipher(ckKey).decrypt(in)
?var?n2?int64
?for?i?:=?56;?i?>=?0;?i?-=?8?{
??n2?^=?int64((uint64(in)?>>?i)?&?0xff)
?}
?vv?:=?int32(n2?&?0xff)
?if?vv?<?0?{
??vv?=?-vv
?}
?return?fmt.Sprintf("%02x%016x",?vv,?uint64(out))
}
type?ckCipher?struct?{
?rk?[roundKeys]int32
}
func?newCkCipher(ckKey?int64)?ckCipher?{
?ck?:=?ckCipher{}
?var?ld?[2]int32
?ld[0]?=?int32(ckKey)
?ld[1]?=?int32(uint64(ckKey)?>>?32)
?ck.rk[0]?=?-1209970333
?for?i?:=?1;?i?<?roundKeys;?i++?{
??ck.rk[i]?=?ck.rk[i-1]?+?-1640531527
?}
?var?a,?b?int32
?var?i,?j?int
?for?k?:=?0;?k?<?3*roundKeys;?k++?{
??ck.rk[i]?=?rotateLeft(ck.rk[i]+(a+b),?3)
??a?=?ck.rk[i]
??ld[j]?=?rotateLeft(ld[j]+(a+b),?a+b)
??b?=?ld[j]
??i?=?(i?+?1)?%?roundKeys
??j?=?(j?+?1)?%?2
?}
?return?ck
}
func?(ck?ckCipher)?encrypt(in?int64)?int64?{
?a?:=?int32(in)?+?ck.rk[0]
?b?:=?int32(uint64(in)>>32)?+?ck.rk[1]
?for?r?:=?1;?r?<=?rounds;?r++?{
??a?=?rotateLeft(a^b,?b)?+?ck.rk[2*r]
??b?=?rotateLeft(b^a,?a)?+?ck.rk[2*r+1]
?}
?return?pkLong(a,?b)
}
func?(ck?ckCipher)?decrypt(in?int64)?int64?{
?a?:=?int32(in)
?b?:=?int32(uint64(in)?>>?32)
?for?i?:=?rounds;?i?>?0;?i--?{
??b?=?rotateRight(b-ck.rk[2*i+1],?a)?^?a
??a?=?rotateRight(a-ck.rk[2*i],?b)?^?b
?}
?b?-=?ck.rk[1]
?a?-=?ck.rk[0]
?return?pkLong(a,?b)
}
func?rotateLeft(x?int32,?y?int32)?int32?{
?return?int32(x<<(y&(32-1)))?|?int32(uint32(x)>>(32-(y&(32-1))))
}
func?rotateRight(x?int32,?y?int32)?int32?{
?return?int32(uint32(x)>>(y&(32-1)))?|?int32(x<<(32-(y&(32-1))))
}
func?pkLong(a?int32,?b?int32)?int64?{
?return?(int64(a)?&?0xffffffff)?|?(int64(b)?<<?32)
}
但到了Linux上,就會(huì)報(bào)錯(cuò):

#?command-line-arguments
./http_register.go:113:15:?invalid?operation:?uint64(in)?>>?i?(shift?count?type?int,?must?be?unsigned?integer)
./http_register.go:175:16:?invalid?operation:?x?<<?(y?&?(32?-?1))?(shift?count?type?int32,?must?be?unsigned?integer)
./http_register.go:175:47:?invalid?operation:?uint32(x)?>>?(32?-?y?&?(32?-?1))?(shift?count?type?int32,?must?be?unsigned?integer)
./http_register.go:179:24:?invalid?operation:?uint32(x)?>>?(y?&?(32?-?1))?(shift?count?type?int32,?must?be?unsigned?integer)
./http_register.go:179:47:?invalid?operation:?x?<<?(32?-?y?&?(32?-?1))?(shift?count?type?int32,?must?be?unsigned?integer)
而在Mac上進(jìn)行交叉編譯[1]:
CGO_ENABLED=0?GOOS=linux?GOARCH=amd64?go?build?文件名.go
(如果出現(xiàn)GOROOT blabla之類的,執(zhí)行go env -w GO111MODULE=off )
也沒有什么問題

導(dǎo)致這種情況的原因,可能因Go版本不同而導(dǎo)致


Mac上的Go版本為 1.16, 而Linux上Go版本為 1.11
解決:
最初想看一下有沒有在線的不同Go版本執(zhí)行工具,無果而終.
想到之前用php時(shí),用過brew switch
來切換不同的php版本.但搜索之后發(fā)現(xiàn),這個(gè)命令被 brew 棄用了.
之前用過node版本工具nvm
,于是試圖找尋Go有沒有類似工具,發(fā)現(xiàn)了gvm.
“安裝gvm
$?bash?<?<(curl?-s?-S?-L?https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
N.B. : 不同操作系統(tǒng)還需要安裝所需依賴,如Mac需要執(zhí)行brew install mercurial
安裝mercurial。具體見原始項(xiàng)目[2]
另外如果出現(xiàn)“ERROR: Unrecognized command line argument: 'use'”報(bào)錯(cuò),可參考此文[3],執(zhí)行:
cp?-rp?.gvm/scripts/env/use?.gvm/scripts/use
chmod?775?.gvm/scripts/use
“安裝go 1.11
gvm?install?go1.11

“選擇版本
gvm?use?go1.11

果然已經(jīng)變?yōu)?Go 1.11
在 Go 1.11 環(huán)境下執(zhí)行,果然出現(xiàn)了和在Linux上Go 1.11下出現(xiàn)的同樣錯(cuò)誤

gvm更多命令
“查看版本
??gvm?list
gvm?gos?(installed)
=>?go1.11
???system
“查看Go的所有版本 (版本來源于源碼中的 tag 標(biāo)簽)
點(diǎn)擊查看Go所有版本:
?gvm?listall
gvm?gos?(available)
???go1
???go1.0.1
???go1.0.2
???go1.0.3
???go1.1
???go1.1rc2
???go1.1rc3
???go1.1.1
???go1.1.2
???go1.2
???go1.2rc2
???go1.2rc3
???go1.2rc4
???go1.2rc5
???go1.2.1
???go1.2.2
???go1.3
???go1.3beta1
???go1.3beta2
???go1.3rc1
???go1.3rc2
???go1.3.1
???go1.3.2
???go1.3.3
???go1.4
???go1.4beta1
???go1.4rc1
???go1.4rc2
???go1.4.1
???go1.4.2
???go1.4.3
???go1.5
???go1.5beta1
???go1.5beta2
???go1.5beta3
???go1.5rc1
???go1.5.1
???go1.5.2
???go1.5.3
???go1.5.4
???go1.6
???go1.6beta1
???go1.6beta2
???go1.6rc1
???go1.6rc2
???go1.6.1
???go1.6.2
???go1.6.3
???go1.6.4
???go1.7
???go1.7beta1
???go1.7beta2
???go1.7rc1
???go1.7rc2
???go1.7rc3
???go1.7rc4
???go1.7rc5
???go1.7rc6
???go1.7.1
???go1.7.2
???go1.7.3
???go1.7.4
???go1.7.5
???go1.7.6
???go1.8
???go1.8beta1
???go1.8beta2
???go1.8rc1
???go1.8rc2
???go1.8rc3
???go1.8.1
???go1.8.2
???go1.8.3
???go1.8.4
???go1.8.5
???go1.8.5rc4
???go1.8.5rc5
???go1.8.6
???go1.8.7
???go1.9
???go1.9beta1
???go1.9beta2
???go1.9rc1
???go1.9rc2
???go1.9.1
???go1.9.2
???go1.9.3
???go1.9.4
???go1.9.5
???go1.9.6
???go1.9.7
???go1.10
???go1.10beta1
???go1.10beta2
???go1.10rc1
???go1.10rc2
???go1.10.1
???go1.10.2
???go1.10.3
???go1.10.4
???go1.10.5
???go1.10.6
???go1.10.7
???go1.10.8
???go1.11
???go1.11beta1
???go1.11beta2
???go1.11beta3
???go1.11rc1
???go1.11rc2
???go1.11.1
???go1.11.2
???go1.11.3
???go1.11.4
???go1.11.5
???go1.11.6
???go1.11.7
???go1.11.8
???go1.11.9
???go1.11.10
???go1.11.11
???go1.11.12
???go1.11.13
???go1.12
???go1.12beta1
???go1.12beta2
???go1.12rc1
???go1.12.1
???go1.12.2
???go1.12.3
???go1.12.4
???go1.12.5
???go1.12.6
???go1.12.7
???go1.12.8
???go1.12.9
???go1.12.10
???go1.12.11
???go1.12.12
???go1.12.13
???go1.12.14
???go1.12.15
???go1.12.16
???go1.12.17
???go1.13
???go1.13beta1
???go1.13rc1
???go1.13rc2
???go1.13.1
???go1.13.2
???go1.13.3
???go1.13.4
???go1.13.5
???go1.13.6
???go1.13.7
???go1.13.8
???go1.13.9
???go1.13.10
???go1.13.11
???go1.13.12
???go1.13.13
???go1.13.14
???go1.13.15
???go1.14
???go1.14beta1
???go1.14rc1
???go1.14.1
???go1.14.2
???go1.14.3
???go1.14.4
???go1.14.5
???go1.14.6
???go1.14.7
???go1.14.8
???go1.14.9
???go1.14.10
???go1.14.11
???go1.14.12
???go1.14.13
???go1.14.14
???go1.14.15
???go1.15
???go1.15beta1
???go1.15rc1
???go1.15rc2
???go1.15.1
???go1.15.2
???go1.15.3
???go1.15.4
???go1.15.5
???go1.15.6
???go1.15.7
???go1.15.8
???go1.15.9
???go1.15.10
???go1.15.11
???go1.15.12
???go1.16
???go1.16beta1
???go1.16rc1
???go1.16.1
???go1.16.2
???go1.16.3
???go1.16.4
???release.r56
???release.r57
???release.r58
???release.r59
???release.r60
???release.r57.1
???release.r57.2
???release.r58.1
???release.r58.2
???release.r60.1
???release.r60.2
???release.r60.3
其他方案--IDE
不管對于Python,還是Golang,面對版本問題時(shí),使用PyCharm或GoLand,始終是極好的選擇
但現(xiàn)在只能下載最近幾個(gè)版本,更久遠(yuǎn)的無法安裝


其他方案--Docker
docker pull golang:1.xx
docker run -it --name golang-1.xx自定義名稱 golang:1.xx
進(jìn)入到容器中(默認(rèn)是基于ubuntu的鏡像)
(如果沒有vi/vim)切換源,安裝vim
mv?/etc/apt/sources.list?/etc/apt/sources.list.bak
echo??"deb?http://mirrors.tuna.tsinghua.edu.cn/debian/?buster?main?contrib?non-free"?>/etc/apt/sources.list
echo??"deb?http://mirrors.tuna.tsinghua.edu.cn/debian/?buster-updates?main?contrib?non-free"?>>/etc/apt/sources.list
echo??"deb?http://mirrors.tuna.tsinghua.edu.cn/debian/?buster-backports?main?contrib?non-free"?>>/etc/apt/sources.list
echo??"deb?http://mirrors.tuna.tsinghua.edu.cn/debian-security?buster/updates?main?contrib?non-free"?>>/etc/apt/sources.list
apt-get?update
apt-get?install?-y?vim

這種方式是萬能的,任何版本都可以得到 (但是都是Linux版本的~)
其他方案--brew
但如果想用Mac的以往版本的Go,用Docker方式做不到~
還可以用brew
可以在這里[4]找到所有可以安裝的Go版本
(從1.16開始支持m1)

問題解決

切換為Go 1.11.5版本后,IDE會(huì)自動(dòng)報(bào)錯(cuò)
y為int32
,將其強(qiáng)制轉(zhuǎn)為uint32
即可,
i為int
,將其強(qiáng)制轉(zhuǎn)為uint
即可.

參考:
如何靈活地進(jìn)行 Go 版本管理[5]
類似的工具還有g[6]

某位大佬推薦 gvc[7], 能管理很多種語言的版本
參考資料
交叉編譯: https://studygolang.com/articles/14376
[2]原始項(xiàng)目: https://github.com/moovweb/gvm#mac-os-x-requirements
[3]此文: https://blog.csdn.net/qq_45534061/article/details/112256901
[4]這里: https://formulae.brew.sh/formula/go#default
[5]如何靈活地進(jìn)行 Go 版本管理: https://juejin.cn/post/6844903949137346573
[6]g: https://github.com/voidint/g
[7]gvc: https://github.com/moqsien/gvc文章來源:http://www.zghlxwxcb.cn/news/detail-693331.html
本文由 mdnice 多平臺發(fā)布文章來源地址http://www.zghlxwxcb.cn/news/detail-693331.html
到了這里,關(guān)于幾種Go版本管理工具的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!