質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

2157閲覧

Goによるハッシュチェーンの実装とindex out of range [1] with length 1エラーについて

ts21

総合スコア32

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2021/09/09 02:04

やりたいこと

Goで4つの要素(ブロック)からなるハッシュチェーンを実装しています。
まずArrayに4つの要素を準備し、一つ目をハッシュ化します。2つ目以降の要素は前のハッシュとその要素を足してハッシュ化していきます。
各過程で得たハッシュを表示していくプログラムを作るのが目標です。

Goに関しては初心者なのですが、試行錯誤しながらコーディングしてみました。

実際に書いたコード

package main import ( "crypto/sha256" "fmt" ) func main() { Array := [...]string{"0001", "0002", "0003", "0004"} h := sha256.New() //構造体を定義 type Block struct { Index int Data string Hash []byte //crypto/sha256の返り値に合わせたスライス } //構造体配列を定義 type BlockArray []*Block var hashChain BlockArray for i := 0; i < len(Array); i++ { if i == 0 { fmt.Println("index = ", i) h.Write([]byte(Array[i])) hashChain = []*Block{ &Block{i, Array[i], h.Sum(nil)}, } fmt.Printf("Block %x Hash = %x \n", i, hashChain[i].Hash) } else { fmt.Println("index = ", i) message := append([]byte(Array[i]), hashChain[i-1].Hash...) //スライスの結合? h.Write([]byte(message)) fmt.Printf("Block %x Hash = %x \n", i, h.Sum(nil)) hashChain = []*Block{ &Block{i, Array[i], h.Sum(nil)}, } fmt.Printf("Block %x Hash = %x \n", i, hashChain[i].Hash) } fmt.Printf("LatestBlock_Hash= %x \n", hashChain[i].Hash) } }

エラー

実行してみると、以下のエラーが表示されました。

% go run hashChain.go index = 0 Block 0 Hash = 888b19a43b151683c87895f6211d9f8640f97bdc8ef32f03dbe057c8f5e56d32 LatestBlock_Hash= 888b19a43b151683c87895f6211d9f8640f97bdc8ef32f03dbe057c8f5e56d32 index = 1 Block 1 Hash = 6dac394913764d4e0c4beed3aae22375fa8692079798d7dd6502e132935311d3 panic: runtime error: index out of range [1] with length 1 goroutine 1 [running]: main.main() /Users/username/go-crypto-imp/hashChain.go:44 +0x92a exit status 2

for文内で使っているインデックスiが範囲外にあるようなのですが、for文に問題があるのでしょうか

ここでの、44行目はi>0のBlockHashを表示するこの1行です(else文内)

fmt.Printf("Block %x Hash = %x \n", i, hashChain[i].Hash)

また、おかしいのは、index = 1で処理が止まっていること、処理の途中でLatestBlock_HashがBlock 0 Hashと同じ値で表示されていることです。

試行錯誤1

試しに、44行目をコメントアウトして再実行すると、

% go run hashChain.go index = 0 Block 0 Hash = 888b19a43b151683c87895f6211d9f8640f97bdc8ef32f03dbe057c8f5e56d32 LatestBlock_Hash= 888b19a43b151683c87895f6211d9f8640f97bdc8ef32f03dbe057c8f5e56d32 index = 1 Block 1 Hash = 6dac394913764d4e0c4beed3aae22375fa8692079798d7dd6502e132935311d3 panic: runtime error: index out of range [1] with length 1 goroutine 1 [running]: main.main() /Users/username/go-crypto-imp/hashChain.go:46 +0x91b exit status 2 tsudashouki@ts21

つぎは 46行目のLatestBlock_Hashの部分で同様のエラーがでました。

fmt.Printf("LatestBlock_Hash= %x \n", hashChain[i].Hash)

hashChain[i]のインデックスiに値が渡っていないように思えます。

試行錯誤2

シンプルなfor文に変更し、インデックスごとにハッシュを表示する形を試してみました。

for i := 0; i < len(Array); i++ { fmt.Println("index = ", i) h.Write([]byte(Array[i])) hashChain = []*Block{ &Block{i, Array[i], h.Sum(nil)}, } fmt.Printf("Block %x Hash = %x \n", i, hashChain[i].Hash) }

結果はやはり、hashchain[i]の部分(31行目)の部分が問題のようでした。

% go run hashChain.go index = 0 Block 0 Hash = 888b19a43b151683c87895f6211d9f8640f97bdc8ef32f03dbe057c8f5e56d32 index = 1 panic: runtime error: index out of range [1] with length 1 goroutine 1 [running]: main.main() /Users/username/go-crypto-imp/hashChain.go:31 +0x426 exit status 2

このように、いろいろ調べて試してみましたが原因と解決方法がわかりませんでした。
何かの基礎的知識が抜けているのであれば、そのあたりをご指摘もらえると幸甚です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

hashChainの組み立てているところが以下のように書かれていて、
常にhashChainの長さは1です。

go

1hashChain = []*Block{ 2 &Block{i, Array[i], h.Sum(nil)}, 3}

その状態でループを回してi=1になったら該当のエラーになってしまいます。

推測ですが、上記の記述は以下のように書かれるべきなように見えます。

go

1hashChain = append(hashChain, &Block{i, Array[i], h.Sum(nil)})

投稿2021/09/09 04:45

nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ts21

2021/09/09 08:02

ご回答いただきありがとうございます! 指摘していただいた形で書き直すと目標通りに動作しました。 スライスやappendの使い方がわからないままなので勉強します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問