golangでUUIDの生成をライブラリでお試し
仕事でコード書くより
設計の仕事ばっかり、スケジュール管理とかめんどくさいので
他の人やってくんないかな…
UUIDって?
UUID(Universally Unique Identifier)とは、ソフトウェア上でオブジェクトを一意に識別するための識別子である。
ざっくりいうとユニークIDみたいやつ
基本的にはsha1とかmd5とか乱数で生成していたけど
そういったものにフォーマットがついた感じ
例:3cc807ab-8e31-3071-aee4-f8f03781cb91
バージョン
現在1から5までの方法がある
確認用ライブラリ
https://github.com/google/uuid
今度改めて自身でアルゴリズムは検討するが今回はちょっとお試しでやってみる
ソース
package main import ( "github.com/google/uuid" "fmt" ) func main() { fmt.Println("version1 NewUUID --") for i:=0;i<10;i++ { uuidObj, _ := uuid.NewUUID() fmt.Println(" ", uuidObj.String()) } fmt.Println("version2 NewDCESecurity --") for i:=0;i<10;i++ { uuidObj, _ := uuid.NewUUID() domain := uuidObj.Domain() id := uuidObj.ID() uuidObj2, _ := uuid.NewDCESecurity(domain, id) fmt.Println(" ", uuidObj2.String()) } fmt.Println("version3 NewMD5 --") for i:=0;i<10;i++ { uuidObj, _ := uuid.NewUUID() data := []byte("wnw8olzvmjp0x6j7ur8vafs4jltjabi0") uuidObj2 := uuid.NewMD5(uuidObj, data) fmt.Println(" ", uuidObj2.String()) } fmt.Println("version5 NewSHA1 --") for i:=0;i<10;i++ { uuidObj, _ := uuid.NewUUID() data := []byte("wnw8olzvmjp0x6j7ur8vafs4jltjabi0") uuidObj2 := uuid.NewSHA1(uuidObj, data) fmt.Println(" ", uuidObj2.String()) } fmt.Println("version4 NewRandom --") for i:=0;i<10;i++ { uuidObj, _ := uuid.NewRandom() fmt.Println(" ", uuidObj.String()) } }
結果
mshige1979MBA:golang matsumotoshigeharu$ go run sample1.go version1 NewUUID -- ef45b54c-9f70-11e9-a730-6476baad914e ef45c294-9f70-11e9-a730-6476baad914e ef45c2b2-9f70-11e9-a730-6476baad914e ef45c2c6-9f70-11e9-a730-6476baad914e ef45c2e4-9f70-11e9-a730-6476baad914e ef45c2f8-9f70-11e9-a730-6476baad914e ef45c316-9f70-11e9-a730-6476baad914e ef45c334-9f70-11e9-a730-6476baad914e ef45c352-9f70-11e9-a730-6476baad914e ef45c366-9f70-11e9-a730-6476baad914e version2 NewDCESecurity -- ef45c38e-9f70-21e9-a730-6476baad914e ef45c3ac-9f70-21e9-a730-6476baad914e ef45c3ca-9f70-21e9-a731-6476baad914e ef45c3e8-9f70-21e9-a732-6476baad914e ef45c410-9f70-21e9-a732-6476baad914e ef45c442-9f70-21e9-a732-6476baad914e ef45c46a-9f70-21e9-a733-6476baad914e ef45c49c-9f70-21e9-a733-6476baad914e ef45c4c4-9f70-21e9-a734-6476baad914e ef45c4ec-9f70-21e9-a735-6476baad914e version3 NewMD5 -- 3cc807ab-8e31-3071-aee4-f8f03781cb91 7e7e001e-6957-38d5-b035-41926dd035dd 91d52425-9470-3e2b-8e5f-649b7b4ec795 157ffb9e-d6b2-3b99-9fca-1d347f60b3e3 33b0480d-6d5f-358a-a37a-893e5850fa62 4b41d96b-dd72-3314-9cc2-1ab241eacb30 9337ce23-6909-3137-98d2-a9372bf57692 1e15f3d0-a040-3eca-a8bc-c677bc8bc619 b90f3b5d-059c-3c0e-b3d8-85c577763bf6 f741b68d-a9d2-3396-b499-745920a718ff version5 NewSHA1 -- 13f575fa-02d7-5c38-8e66-48524dd233a4 a56079b2-5373-5656-911a-483e3a92f19c 18c2d54b-1a94-5928-8a4a-2f3dd5fc3e57 8ac4f8a2-89b8-5ea3-81eb-d1654deaab51 bb6bff8b-615f-5791-a9fb-e3543fd9d02e 8209f28f-ccc9-5a90-beaf-d7e8e9927183 387ab566-8b80-5c6c-a156-8e49a5c9c3fe 75a4de2d-8049-5bb1-80c9-7250959af3d2 5991cc2e-2bac-5f83-9ae0-b4a45882a11a b8e33f96-449d-5972-8c9c-98b0487549dd version4 NewRandom -- 01a2c8b4-e3ec-4df5-a027-b7ffe5c6ed5d eb2aa249-3614-4833-b979-99c87c4189a8 4c8bda02-4b27-460a-b46f-d65b4e4f5e48 23df6b4c-e10f-4bcd-b935-0224f3216680 2ab1a839-08b2-4069-9bd7-a772c5934e66 dab1ade8-a446-4609-844b-257a7ab1ba0b eb770f37-a59a-4888-9789-d585f514ae93 b9999fdb-cd20-4bdb-b671-6228667a6746 8160d492-1ead-4d33-b4e8-d242cf2df332 63b96ec6-e9d7-4fa4-abb7-31b9e12fca0d
PlantUMLをVisualStudioCodeで書く
curlを最新版へソースインストール
ruby関連の勉強を始めてみようとしたけど
なんか出る
/tmp/ruby-build.20181006035131.5059 ~/.rbenv/plugins/ruby-build curl: (35) Peer reports incompatible or unsupported protocol version. ~
環境
vangrant上のcentos7(64bit)
なんかcurlが古いらしい
$ curl -V curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.15.4 zlib/1.2.7 libidn/1.28 libssh2/1.4.3 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz $
証明書関連で動かなくなった感じ?
最新をソースコードよりインストールする
yumでツールをインストール
sudo yum install -y openssl-devel libmetalink-devel libssh2-devel c-ares-devel lbzip2
ダウンロード&インストール
wget https://curl.haxx.se/download/curl-7.61.1.tar.gz tar zxf curl-7.61.1.tar.gz cd curl-7.61.1 ./configure --enable-libcurl-option make sudo make install
インストールパスを間違えたので古いやつを削除してリンクにする
sudo rm -f /usr/bin/curl sudo ln -s /usr/local/bin/curl /usr/bin/curl
確認
$ curl -V curl 7.61.1 (x86_64-pc-linux-gnu) libcurl/7.61.1 OpenSSL/1.0.2k zlib/1.2.7 Release-Date: 2018-09-05 Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz UnixSockets HTTPS-proxy $
rbenvでインストールができるようになった\(^o^)/
[vagrant@localhost ~]$ rbenv install 2.3.7 Downloading ruby-2.3.7.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.7.tar.bz2 Installing ruby-2.3.7... Installed ruby-2.3.7 to /home/vagrant/.rbenv/versions/2.3.7 [vagrant@localhost ~]$
参考
cURLの最新版をインストールする | スターフィールド株式会社
ありがとうございます
go言語の学習:websocketで画像を送信し、webで表示
できたの
なにこれ?
websocketサーバより1秒単位で画像をバイナリ形式で送信したもの
ソース(サーバ側)
package main import ( "log" "net/http" "golang.org/x/net/websocket" "time" "io/ioutil" "image" "gocv.io/x/gocv" "image/color" "bytes" "image/jpeg" "os/user" ) var ( black = color.RGBA{0, 0, 0, 0} ) func main() { name := "server" log.Println(name + " start") http.Handle("/ws", websocket.Handler(WsHandler)) err := http.ListenAndServe(":8001", nil) if err != nil { panic("ListenAndServe: " + err.Error()) } log.Println(name + " end") } func WsHandler(ws *websocket.Conn) { log.Println("connect") // 自動送信 go autoSend(ws) // 受信処理監視 for { var b []byte err := websocket.Message.Receive(ws, &b) if err != nil { log.Println(err) break } } } // 任意の画像を送信する func autoSend(ws *websocket.Conn) { t := time.NewTicker(1 * time.Second) for { select { case <-t.C: // ユーザディレクトリ取得 user, err := user.Current() if err != nil { log.Println(err) return } // 画像ファイル読み込み b, err := ioutil.ReadFile(user.HomeDir + "/Desktop/" + "pug3_pic1.jpg") if err != nil { break } // 画像変換 atom, err := gocv.IMDecode(b, gocv.IMReadUnchanged) if err != nil { log.Println(err) return } defer atom.Close() // 日時取得 now := time.Now() // 偶数 if int(now.Second()) % 2 == 0 { gocv.Rectangle(&atom, image.Rect(400, 400, 900, 700), black, 2) } else { gocv.Rectangle(&atom, image.Rect(400, 400, 900, 700), black, -1) } // 文字列を出力 timeStr := now.Format("2006/01/02 15:04:05") gocv.PutText(&atom, timeStr, image.Pt(20, atom.Rows() - 40), gocv.FontHersheyComplex, 1, black, 1) // 画像に変換 image, err := atom.ToImage() if err != nil { log.Println(err) return } var jpegBytes []byte buf := bytes.NewBuffer(jpegBytes) if err := jpeg.Encode(buf, image, nil); err != nil { log.Println(err) } b = buf.Bytes() websocket.Message.Send(ws, b) log.Println("send") } } }
ソース(クライアント側)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <img id="img1" src=""> <script> var uri = "ws://localhost:8001" + "/ws"; webSocket = new WebSocket(uri); webSocket.binaryType = 'blob'; webSocket.onopen = function(e) { console.log("open"); }; webSocket.onmessage = function(e) { console.log("message"); var data = e.data; if (data.constructor === Blob) { document.getElementById('img1').src = URL.createObjectURL(data); } }; webSocket.onclose = function(e) { console.log("close"); }; </script> </body> </html>
ソース(クライアント版2)
package main import ( "log" "golang.org/x/net/websocket" "strconv" ) var ( doneCh chan bool origin = "http://localhost:8001/" url = "ws://localhost:8001/ws" ) func main() { name := "client" log.Println(name + " start") doneCh = make(chan bool) ws, err := websocket.Dial(url, "", origin) if err != nil { log.Fatal(err) return } go receiveMsg(ws) <-doneCh log.Println(name + " end") } // 受信 func receiveMsg(ws *websocket.Conn) { var b []byte for { err := websocket.Message.Receive(ws, &b) if err != nil { log.Println(err) doneCh <- true break } log.Printf("Receive datasize=" + strconv.Itoa(len(b))) } }
所感
いろいろ悩んだけど基本は画像をバイナリで送信するだけだった感じ
動画のストリーミングという感じではないのでそこまで難しくないかも…
最初はwebsocketの送受信がうまく行かなかったけどw
go言語の学習:画像を読み込み、文字を追加
日本語ができない
時間は気にしないでwww
前のソースを一部回収
package main import ( "gocv.io/x/gocv" "log" "os/user" "time" "io/ioutil" "image/color" "image" ) var ( // サイズ w = 640 h = 480 // 色定義 black = color.RGBA{0, 0, 0, 0} blue = color.RGBA{0, 0, 255, 0} red = color.RGBA{255, 0, 0, 0} white = color.RGBA{255, 255, 255, 0} yellow = color.RGBA{255, 255, 0, 0} color2 = color.RGBA{128,128,128,0} ) func main() { // ユーザディレクトリ取得して保存先を作成 user, err := user.Current() if err != nil { log.Println(err) return } // img読み込み img_file_path := user.HomeDir + "/Desktop/" + "pug3_pic1.jpg" // file b, err := ioutil.ReadFile(img_file_path) if err != nil { log.Println(err) return } // 画像取得 atom, err := gocv.IMDecode(b, gocv.IMReadUnchanged) if err != nil { log.Println(err) return } defer atom.Close() // sample1描画 sample1(&atom) // 領域作成 img2 := gocv.NewMatWithSize(atom.Rows(), atom.Cols(), atom.Type()) // 短径(線) gocv.Rectangle(&img2, image.Rect(400, 20, 900, 400), blue, 3) // 短径(塗りつぶし) gocv.Rectangle(&img2, image.Rect(400, 20, 900, 400), color2, -1) // 重ねる gocv.AddWeighted(atom, 1, img2, 0.5, 0, &atom) // 文字列を出力 timeStr := time.Now().Format("2006/01/02 15:04:05") gocv.PutText(&atom, timeStr, image.Pt(20, atom.Rows() - 40), gocv.FontHersheyComplex, 1, black, 1) // 出力画像パス file_path := user.HomeDir + "/Desktop/" + time.Now().Format("20060102150405") + ".jpg" // 保存 gocv.IMWrite(file_path, atom) } func sample1 (img *gocv.Mat) { // 短径描画 gocv.Rectangle(img,image.Rect(10, 10, 100, 100), black, 5) gocv.Rectangle(img,image.Rect(200, 15, 300, 350), blue, 5) gocv.Rectangle(img,image.Rect(10, 400, 600, 470), yellow, -1) // -1の場合は塗りつぶし gocv.Rectangle(img,image.Rect(40, 350, 550, 450), red, -1) // -1の場合は塗りつぶし // 多角形描画 ps := make([][]image.Point, 1) p := make([]image.Point, 4) p[0] = image.Pt(int(0.1*float64(w)), int(0.1*float64(h))) p[1] = image.Pt(int(0.1*float64(w)), int(0.4*float64(h))) p[2] = image.Pt(int(0.3*float64(w)), int(0.2*float64(h))) p[3] = image.Pt(int(0.3*float64(w)), int(0.1*float64(h))) ps[0] = p gocv.DrawContours(img, ps, 0, red, -1) // -1の場合は塗りつぶし }
使うようになったもの
gocv.IMDecode
→ バイナリを読み込んで変換してくれる
gocv.AddWeighted
→ 既存の短径領域に別の短径領域を重ねる
gocv.PutText
→ 指定の場所にテキストを追加
所感
IDEってやっぱり良いです\(^o^)/
viなどでもなんかできそうですけど、commandキーや入力している間に引数やメソッドの候補がでるのは嬉しい
go言語の学習:gocvで画像を作成して出力
gocv
Home :: GoCV - Golang Computer Vision Using OpenCV 3
opencvでなんかいろいろやってくれるライブラリ
インストールするまでくっそ面倒
macの場合はbrew installで簡単そうですけど
なんかいろいろエラーでて大変でした
・pythonいれたり、クリーンアップしたり、brew docterして問題解決したり色々やったなあ…
・多分、最新バージョンならwindowsでもできると思います
ソース
package main import ( "image" "image/color" "gocv.io/x/gocv" "log" "os/user" "time" "os" "image/jpeg" ) var w = 640 var h = 480 func main() { // 描画領域作成 atom := gocv.NewMatWithSize(h, w, gocv.MatTypeCV8UC3) defer atom.Close() // 色定義 black := color.RGBA{0, 0, 0, 0} blue := color.RGBA{0, 0, 255, 0} red := color.RGBA{255, 0, 0, 0} white := color.RGBA{255, 255, 255, 0} yellow := color.RGBA{255, 255, 0, 0} // 短径描画 gocv.Rectangle(&atom,image.Rect(0, 0, 640, 480), white, -1) gocv.Rectangle(&atom,image.Rect(10, 10, 100, 100), black, 5) gocv.Rectangle(&atom,image.Rect(200, 15, 300, 350), blue, 5) gocv.Rectangle(&atom,image.Rect(10, 400, 600, 470), yellow, -1) // -1の場合は塗りつぶし gocv.Rectangle(&atom,image.Rect(40, 350, 550, 450), red, -1) // -1の場合は塗りつぶし // 多角形描画 ps := make([][]image.Point, 1) p := make([]image.Point, 4) p[0] = image.Pt(int(0.1*float64(w)), int(0.1*float64(h))) p[1] = image.Pt(int(0.1*float64(w)), int(0.4*float64(h))) p[2] = image.Pt(int(0.3*float64(w)), int(0.2*float64(h))) p[3] = image.Pt(int(0.3*float64(w)), int(0.1*float64(h))) ps[0] = p gocv.DrawContours(&atom, ps, 0, red, -1) // -1の場合は塗りつぶし // ユーザディレクトリ取得して保存先を作成 user, err := user.Current() if err != nil { log.Println(err) return } file_path := user.HomeDir + "/Desktop/" + time.Now().Format("20060102150405") + ".jpg" // 保存 //gocv.IMWrite(file_path, atom) // 画像に変換 image, err := atom.ToImage() if err != nil { log.Println(err) return } // file出力 file, errOs := os.Create(file_path) if errOs != nil { log.Println(err) return } defer file.Close() // jpeg形式で出力 if err := jpeg.Encode(file, image, &jpeg.Options{100}); err != nil { log.Println(err) return } /* // bytes変換 var jpegBytes []byte buf := bytes.NewBuffer(jpegBytes) if err := jpeg.Encode(buf, image, nil); err != nil { log.Println(err) } jpegBytes = buf.Bytes() */ }
できたもの(適当)
所感
複雑な画像編集することが容易にできるような感じとのこと
文字入れたり、グレースケールとかできたらやってみたい
go言語の学習:構造体よりタグ情報を取得
構造体にあるjsonなどのタグより取得
package main import ( "fmt" "reflect" ) type Sample struct { no int `sampletag:"aaaaa"` name string `sampletag:"bbbbb"` age int `sampletag:"ccccc"` } func main() { fmt.Println("start") // Sample1インターフェースを定義 var sample1 Sample // 型の取得 t := reflect.TypeOf(sample1) // タグの情報を取得 for i:=0;i<t.NumField();i++ { item := t.Field(i) fmt.Printf("index: %2d, name:%10s, type:%10s, tag:%10s\n", i, item.Name, item.Type.Name(), item.Tag.Get("sampletag")) } fmt.Println("end") }
↓
start index: 0, name: no, type: int, tag: aaaaa index: 1, name: name, type: string, tag: bbbbb index: 2, name: age, type: int, tag: ccccc end
DBのORMやjsonのエンコード、デコードなどで使用されている
タグ情報を設定することで構造体の項目のバリデーションなどにも併用できる感じ…