go-multihash update
Juan Batiz-Benet committed
Feb 7, 2015 at 12:53 UTC
a4c522bcd460ac21c339509ccd149d7c8fc73081
19 files changed
+600
-2
Godeps/Godeps.json
+2
-2
@@ -176,8 +176,8 @@
176
},
177
{
178
"ImportPath": "github.com/jbenet/go-multihash",
179
- "Comment": "0.1.0-19-g8ce5cb1",
180
- "Rev": "8ce5cb1b82e1b4c1bea1fdf3cd467ef49301734e"
179
+ "Comment": "0.1.0-33-g4e09420",
180
+ "Rev": "4e09420ceb2db37a5fbb149821b9e63d88d47218"
181
},
182
{
183
"ImportPath": "github.com/jbenet/go-peerstream",
Godeps/_workspace/src/github.com/jbenet/go-multihash/.travis.yml
new
+11
@@ -0,0 +1,11 @@
1
+language: go
2
+
3
+go:
4
+ - 1.3
5
+ - release
6
+ - tip
7
+
8
+script:
9
+ - make test
10
+
11
+env: TEST_VERBOSE=1
Godeps/_workspace/src/github.com/jbenet/go-multihash/Makefile
new
+11
@@ -0,0 +1,11 @@
1
+test: go_test other_tests
2
+
3
+other_tests:
4
+ cd test && make test
5
+
6
+go_test: go_deps
7
+ go test -race -cpu=5 -v ./...
8
+
9
+go_deps:
10
+ go get code.google.com/p/go.crypto/sha3
11
+ go get github.com/jbenet/go-base58
Godeps/_workspace/src/github.com/jbenet/go-multihash/README.md
+2
@@ -1,5 +1,7 @@
1
# go-multihash
2
3
+
4
+
5
[multihash](//github.com/jbenet/multihash) implementation in Go.
6
7
## Example
Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/.gitignore
new
+1
@@ -0,0 +1 @@
1
+multihash
Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/README.md
new
+116
@@ -0,0 +1,116 @@
1
+# multihash tool
2
+
3
+The `multihash` tool uses `go-multihash` to hash things much like `shasum`.
4
+
5
+Warning: this is a **multihash** tool! Its digests follow the [multihash](https://github.com/jbenet/multihash) format.
6
+
7
+### Install
8
+
9
+```
10
+go get github.com/jbenet/go-multihash/multihash
11
+```
12
+
13
+### Usage
14
+
15
+```sh
16
+> multihash -h
17
+usage: ./multihash [options] [FILE]
18
+Print or check multihash checksums.
19
+With no FILE, or when FILE is -, read standard input.
20
+
21
+Options:
22
+ -a="sha2-256": one of: sha1, sha2-256, sha2-512, sha3 (shorthand)
23
+ -algorithm="sha2-256": one of: sha1, sha2-256, sha2-512, sha3
24
+ -c="": check checksum matches (shorthand)
25
+ -check="": check checksum matches
26
+ -e="base58": one of: raw, hex, base58, base64 (shorthand)
27
+ -encoding="base58": one of: raw, hex, base58, base64
28
+ -l=-1: checksums length in bits (truncate). -1 is default (shorthand)
29
+ -length=-1: checksums length in bits (truncate). -1 is default
30
+```
31
+
32
+### Examples
33
+
34
+#### Input
35
+
36
+```sh
37
+# from stdin
38
+> multihash < main.go
39
+QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8
40
+
41
+# from file
42
+> ./multihash main.go
43
+QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8
44
+
45
+# from stdin "filename"
46
+> multihash - < main.go
47
+QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8
48
+```
49
+
50
+#### Algorithms
51
+
52
+```sh
53
+> multihash -a ?
54
+error: algorithm '?' not one of: sha1, sha2-256, sha2-512, sha3
55
+
56
+> multihash -a sha1 < main.go
57
+5drkbcqJUo6fZVvcZJeVEVWAgndvLm
58
+
59
+> multihash -a sha2-256 < main.go
60
+QmcK3s36goo9v2HYcfTrDKKwxaxmJJ59etodQQFYsL5T5N
61
+
62
+> multihash -a sha2-512 < main.go
63
+8VuDcW4CooyPQA8Cc4eYpwjhyDJZqu5m5ZMDFzWULYsVS8d119JaGeNWsZbZ2ZG2kPtbrMx31MidokCigaD65yUPAs
64
+
65
+> multihash -a sha3 < main.go
66
+8tWDCTfAX24DYmzNixTj2ARJkqwRG736VHx5aJppmqRjhW9QT1EuTgKUmu9Pmunzq292jzPKxb2VxSsTXmjFY1HD3B
67
+```
68
+
69
+#### Encodings
70
+
71
+```sh
72
+> multihash -e raw < main.go
73
+ Ϛ�����I�5 S��WG>���_��]g�����u
74
+
75
+> multihash -e hex < main.go
76
+1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275
77
+
78
+> multihash -e base64 < main.go
79
+EiDPmqK4o4ubSdE1CVOQBZpXRz6XrOtfyuJdZ6i2/rWCdQ==
80
+
81
+> multihash -e base58 < main.go
82
+Qmf1QjEXDmqBm7RqHKqFGNUyhzUjnX7cmgKMrGzzPceZDQ
83
+```
84
+
85
+#### Digest Length
86
+
87
+```sh
88
+# we're outputing hex (good byte alignment) to show the codes changing
89
+# notice the multihash code (first 2 chars) differs!
90
+> multihash -e hex -a sha2-256 -l 256 < main.go
91
+1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275
92
+> multihash -e hex -a sha2-512 -l 256 < main.go
93
+132047a4b6c629f5545f529b0ff461dc09119969f3593186277a1cc7a8ea3560a6f1
94
+> multihash -e hex -a sha3 -l 256 < main.go
95
+14206b9222a1a47939e665261bd2b5573e55e7988675223adde73c1011066ad66335
96
+
97
+# notice the multihash length (next 2 chars) differs!
98
+> multihash -e hex -a sha2-256 -l 256 < main.go
99
+1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275
100
+> multihash -e hex -a sha2-256 -l 200 < main.go
101
+1219cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d
102
+```
103
+
104
+#### Verify Checksum
105
+
106
+```sh
107
+> multihash -c QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 < main.go
108
+OK checksums match (-q for no output)
109
+
110
+> multihash -c QmcKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa < main.go
111
+error: computed checksum did not match (-q for no output)
112
+
113
+# works with other arguments too
114
+> multihash -e hex -l 128 -c "12102ffc284a1e82bf51e567c75b2ae6edb9" < main.go
115
+OK checksums match (-q for no output)
116
+```
Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/coding.go
new
+40
@@ -0,0 +1,40 @@
1
+package main
2
+
3
+import (
4
+ "encoding/base64"
5
+ "encoding/hex"
6
+ "fmt"
7
+
8
+ base58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
9
+ mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
10
+)
11
+
12
+func Decode(encoding, digest string) (mh.Multihash, error) {
13
+ switch encoding {
14
+ case "raw":
15
+ return mh.Cast([]byte(digest))
16
+ case "hex":
17
+ return hex.DecodeString(digest)
18
+ case "base58":
19
+ return base58.Decode(digest), nil
20
+ case "base64":
21
+ return base64.StdEncoding.DecodeString(digest)
22
+ default:
23
+ return nil, fmt.Errorf("unknown encoding: %s", encoding)
24
+ }
25
+}
26
+
27
+func Encode(encoding string, hash mh.Multihash) (string, error) {
28
+ switch encoding {
29
+ case "raw":
30
+ return string(hash), nil
31
+ case "hex":
32
+ return hex.EncodeToString(hash), nil
33
+ case "base58":
34
+ return base58.Encode(hash), nil
35
+ case "base64":
36
+ return base64.StdEncoding.EncodeToString(hash), nil
37
+ default:
38
+ return "", fmt.Errorf("unknown encoding: %s", encoding)
39
+ }
40
+}
Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/main.go
new
+208
@@ -0,0 +1,208 @@
1
+package main
2
+
3
+import (
4
+ "bytes"
5
+ "flag"
6
+ "fmt"
7
+ "io"
8
+ "io/ioutil"
9
+ "os"
10
+ "strings"
11
+
12
+ mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
13
+)
14
+
15
+var usage = `usage: %s [options] [FILE]
16
+Print or check multihash checksums.
17
+With no FILE, or when FILE is -, read standard input.
18
+
19
+Options:
20
+`
21
+
22
+// flags
23
+var encodings = []string{"raw", "hex", "base58", "base64"}
24
+var algorithms = []string{"sha1", "sha2-256", "sha2-512", "sha3"}
25
+var encoding string
26
+var algorithm string
27
+var algorithmCode int
28
+var length int
29
+var checkRaw string
30
+var checkMh mh.Multihash
31
+var inputFilename string
32
+var quiet bool
33
+
34
+// joined names
35
+var algoStr string
36
+var encStr string
37
+
38
+func init() {
39
+ flag.Usage = func() {
40
+ fmt.Fprintf(os.Stderr, usage, os.Args[0])
41
+ flag.PrintDefaults()
42
+ }
43
+
44
+ algoStr = "one of: " + strings.Join(algorithms, ", ")
45
+ flag.StringVar(&algorithm, "algorithm", "sha2-256", algoStr)
46
+ flag.StringVar(&algorithm, "a", "sha2-256", algoStr+" (shorthand)")
47
+
48
+ encStr = "one of: " + strings.Join(encodings, ", ")
49
+ flag.StringVar(&encoding, "encoding", "base58", encStr)
50
+ flag.StringVar(&encoding, "e", "base58", encStr+" (shorthand)")
51
+
52
+ checkStr := "check checksum matches"
53
+ flag.StringVar(&checkRaw, "check", "", checkStr)
54
+ flag.StringVar(&checkRaw, "c", "", checkStr+" (shorthand)")
55
+
56
+ lengthStr := "checksums length in bits (truncate). -1 is default"
57
+ flag.IntVar(&length, "length", -1, lengthStr)
58
+ flag.IntVar(&length, "l", -1, lengthStr+" (shorthand)")
59
+
60
+ quietStr := "quiet output (no newline on checksum, no error text)"
61
+ flag.BoolVar(&quiet, "quiet", false, quietStr)
62
+ flag.BoolVar(&quiet, "q", false, quietStr+" (shorthand)")
63
+}
64
+
65
+func strIn(a string, set []string) bool {
66
+ for _, s := range set {
67
+ if s == a {
68
+ return true
69
+ }
70
+ }
71
+ return false
72
+}
73
+
74
+func parseFlags() error {
75
+ flag.Parse()
76
+
77
+ if !strIn(algorithm, algorithms) {
78
+ return fmt.Errorf("algorithm '%s' not %s", algorithm, algoStr)
79
+ }
80
+ var found bool
81
+ algorithmCode, found = mh.Names[algorithm]
82
+ if !found {
83
+ return fmt.Errorf("algorithm '%s' not found (lib error, pls report).")
84
+ }
85
+
86
+ if !strIn(encoding, encodings) {
87
+ return fmt.Errorf("encoding '%s' not %s", encoding, encStr)
88
+ }
89
+
90
+ if checkRaw != "" {
91
+ var err error
92
+ checkMh, err = Decode(encoding, checkRaw)
93
+ if err != nil {
94
+ return fmt.Errorf("fail to decode check '%s': %s", checkRaw, err)
95
+ }
96
+ }
97
+
98
+ if length >= 0 {
99
+ if length%8 != 0 {
100
+ return fmt.Errorf("length must be multiple of 8")
101
+ }
102
+ length = length / 8
103
+
104
+ if length > mh.DefaultLengths[algorithmCode] {
105
+ length = mh.DefaultLengths[algorithmCode]
106
+ }
107
+ }
108
+ return nil
109
+}
110
+
111
+func getInput() (io.ReadCloser, error) {
112
+ args := flag.Args()
113
+
114
+ switch {
115
+ case len(args) < 1:
116
+ inputFilename = "-"
117
+ return os.Stdin, nil
118
+ case args[0] == "-":
119
+ inputFilename = "-"
120
+ return os.Stdin, nil
121
+ default:
122
+ inputFilename = args[0]
123
+ f, err := os.Open(args[0])
124
+ if err != nil {
125
+ return nil, fmt.Errorf("failed to open '%s': %s", args[0], err)
126
+ }
127
+ return f, nil
128
+ }
129
+}
130
+
131
+func check(h1 mh.Multihash, r io.Reader) error {
132
+ h2, err := hash(r)
133
+ if err != nil {
134
+ return err
135
+ }
136
+
137
+ if !bytes.Equal(h1, h2) {
138
+ if quiet {
139
+ os.Exit(1)
140
+ }
141
+ return fmt.Errorf("computed checksum did not match (-q for no output)")
142
+ }
143
+
144
+ if !quiet {
145
+ fmt.Println("OK checksums match (-q for no output)")
146
+ }
147
+ return nil
148
+}
149
+
150
+func hash(r io.Reader) (mh.Multihash, error) {
151
+ b, err := ioutil.ReadAll(r)
152
+ if err != nil {
153
+ return nil, err
154
+ }
155
+
156
+ return mh.Sum(b, algorithmCode, length)
157
+}
158
+
159
+func printHash(r io.Reader) error {
160
+ h, err := hash(r)
161
+ if err != nil {
162
+ return err
163
+ }
164
+
165
+ s, err := Encode(encoding, h)
166
+ if err != nil {
167
+ return err
168
+ }
169
+
170
+ if quiet {
171
+ fmt.Print(s)
172
+ } else {
173
+ fmt.Println(s)
174
+ }
175
+ return nil
176
+}
177
+
178
+func main() {
179
+ checkErr := func(err error) {
180
+ if err != nil {
181
+ die("error: ", err)
182
+ }
183
+ }
184
+
185
+ err := parseFlags()
186
+ checkErr(err)
187
+
188
+ inp, err := getInput()
189
+ checkErr(err)
190
+
191
+ if checkMh != nil {
192
+ err = check(checkMh, inp)
193
+ checkErr(err)
194
+ } else {
195
+ err = printHash(inp)
196
+ checkErr(err)
197
+ }
198
+ inp.Close()
199
+}
200
+
201
+func die(v ...interface{}) {
202
+ if !quiet {
203
+ fmt.Fprint(os.Stderr, v...)
204
+ fmt.Fprint(os.Stderr, "\n")
205
+ }
206
+ // flag.Usage()
207
+ os.Exit(1)
208
+}
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/.gitignore
new
+1
@@ -0,0 +1 @@
1
+bin/multihash
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/Makefile
new
+25
@@ -0,0 +1,25 @@
1
+BINS = bin/multihash
2
+MULTIHASH_ROOT = ../
3
+MULTIHASH_CMD = ../multihash
4
+
5
+all: deps
6
+
7
+deps: bins
8
+
9
+clean:
10
+ rm $(BINS)
11
+
12
+bins: $(BINS)
13
+
14
+bin/multihash: $(MULTIHASH_ROOT)/**/*.go
15
+ go build -o bin/multihash $(MULTIHASH_CMD)
16
+
17
+test: test_expensive
18
+
19
+test_expensive:
20
+ cd sharness && make TEST_EXPENSIVE=1
21
+
22
+test_cheap:
23
+ cd sharness && make
24
+
25
+.PHONY: all clean
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/.gitignore
new
+3
@@ -0,0 +1,3 @@
1
+lib/sharness/
2
+test-results/
3
+trash directory.*.sh/
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/Makefile
new
+37
@@ -0,0 +1,37 @@
1
+# Run tests
2
+#
3
+# Copyright (c) 2014 Christian Couder
4
+# MIT Licensed; see the LICENSE file in this repository.
5
+#
6
+
7
+# NOTE: run with TEST_VERBOSE=1 for verbose sharness tests.
8
+
9
+T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
10
+BINS = bin/multihash
11
+SHARNESS = lib/sharness/sharness.sh
12
+
13
+all: clean deps $(T) aggregate
14
+
15
+clean:
16
+ @echo "*** $@ ***"
17
+ -rm -rf test-results
18
+
19
+$(T):
20
+ @echo "*** $@ ***"
21
+ ./$@
22
+
23
+aggregate:
24
+ @echo "*** $@ ***"
25
+ lib/test-aggregate-results.sh
26
+
27
+deps: $(SHARNESS) $(BINS)
28
+
29
+$(SHARNESS):
30
+ @echo "*** installing $@ ***"
31
+ lib/install-sharness.sh
32
+
33
+bin/%:
34
+ @echo "*** installing $@ ***"
35
+ cd .. && make $@
36
+
37
+.PHONY: all clean $(T) aggregate
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/bin
new
+1
@@ -0,0 +1 @@
1
+../bin
\ No newline at end of file
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/install-sharness.sh
new
+26
@@ -0,0 +1,26 @@
1
+#!/bin/sh
2
+# install sharness.sh
3
+#
4
+# Copyright (c) 2014 Juan Batiz-Benet
5
+# MIT Licensed; see the LICENSE file in this repository.
6
+#
7
+
8
+# settings
9
+version=50229a79ba22b2f13ccd82451d86570fecbd194c
10
+urlprefix=https://github.com/mlafeldt/sharness.git
11
+clonedir=lib
12
+sharnessdir=sharness
13
+
14
+die() {
15
+ echo >&2 "$@"
16
+ exit 1
17
+}
18
+
19
+mkdir -p "$clonedir" || die "Could not create '$clonedir' directory"
20
+cd "$clonedir" || die "Could not cd into '$clonedir' directory"
21
+
22
+git clone "$urlprefix" || die "Could not clone '$urlprefix'"
23
+cd "$sharnessdir" || die "Could not cd into '$sharnessdir' directory"
24
+git checkout "$version" || die "Could not checkout '$version'"
25
+
26
+exit 0
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-aggregate-results.sh
new
+17
@@ -0,0 +1,17 @@
1
+#!/bin/sh
2
+#
3
+# Script to aggregate results using Sharness
4
+#
5
+# Copyright (c) 2014 Christian Couder
6
+# MIT Licensed; see the LICENSE file in this repository.
7
+#
8
+
9
+SHARNESS_AGGREGATE="lib/sharness/aggregate-results.sh"
10
+
11
+test -f "$SHARNESS_AGGREGATE" || {
12
+ echo >&2 "Cannot find: $SHARNESS_AGGREGATE"
13
+ echo >&2 "Please check Sharness installation."
14
+ exit 1
15
+}
16
+
17
+ls test-results/t*-*.sh.*.counts | "$SHARNESS_AGGREGATE"
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-lib.sh
new
+43
@@ -0,0 +1,43 @@
1
+# Test framework for go-ipfs
2
+#
3
+# Copyright (c) 2014 Christian Couder
4
+# MIT Licensed; see the LICENSE file in this repository.
5
+#
6
+# We are using sharness (https://github.com/mlafeldt/sharness)
7
+# which was extracted from the Git test framework.
8
+
9
+# Use the multihash tool to test against
10
+
11
+# Add current directory to path, for multihash tool.
12
+PATH=$(pwd)/bin:${PATH}
13
+
14
+# Set sharness verbosity. we set the env var directly as
15
+# it's too late to pass in --verbose, and --verbose is harder
16
+# to pass through in some cases.
17
+test "$TEST_VERBOSE" = 1 && verbose=t
18
+
19
+# assert the `multihash` we're using is the right one.
20
+if test `which multihash` != $(pwd)/bin/multihash; then
21
+ echo >&2 "Cannot find the tests' local multihash tool."
22
+ echo >&2 "Please check test and multihash tool installation."
23
+ exit 1
24
+fi
25
+
26
+SHARNESS_LIB="lib/sharness/sharness.sh"
27
+
28
+. "$SHARNESS_LIB" || {
29
+ echo >&2 "Cannot source: $SHARNESS_LIB"
30
+ echo >&2 "Please check Sharness installation."
31
+ exit 1
32
+}
33
+
34
+# Please put go-multihash specific shell functions below
35
+
36
+for hashbin in sha1sum shasum; do
37
+ if type "$hashbin"; then
38
+ export SHASUMBIN="$hashbin" &&
39
+ test_set_prereq SHASUM &&
40
+ break
41
+ fi
42
+done
43
+
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0010-basics.sh
new
+25
@@ -0,0 +1,25 @@
1
+#!/bin/sh
2
+#
3
+# Copyright (c) 2015 Christian Couder
4
+# MIT Licensed; see the LICENSE file in this repository.
5
+#
6
+
7
+test_description="Basic tests"
8
+
9
+. lib/test-lib.sh
10
+
11
+test_expect_success "current dir is writable" '
12
+ echo "It works!" >test.txt
13
+'
14
+
15
+test_expect_success "multihash is available" '
16
+ type multihash
17
+'
18
+
19
+test_expect_success "multihash help output looks good" '
20
+ test_must_fail multihash -h 2>help.txt &&
21
+ cat help.txt | egrep -i "^usage:" >/dev/null &&
22
+ cat help.txt | egrep -i "multihash .*options.*file" >/dev/null
23
+'
24
+
25
+test_done
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0020-sha1.sh
new
+31
@@ -0,0 +1,31 @@
1
+#!/bin/sh
2
+#
3
+# Copyright (c) 2015 Christian Couder
4
+# MIT Licensed; see the LICENSE file in this repository.
5
+#
6
+
7
+test_description="sha1 tests"
8
+
9
+. lib/test-lib.sh
10
+
11
+test_expect_success "setup sha1 tests" '
12
+ echo "Hash me!" >hash_me.txt &&
13
+ SHA1=bc6f2c3cd945bc754789e50b2f68deee2f421810 &&
14
+ echo "1114$SHA1" >actual
15
+'
16
+
17
+test_expect_success "'multihash -a=sha1 -e=hex' works" '
18
+ multihash -a=sha1 -e=hex hash_me.txt >expected
19
+'
20
+
21
+test_expect_success "'multihash -a=sha1 -e=hex' output looks good" '
22
+ test_cmp expected actual
23
+'
24
+
25
+test_expect_success SHASUM "check hash using shasum" '
26
+ echo "$SHA1 hash_me.txt" >actual &&
27
+ $SHASUMBIN hash_me.txt >expected &&
28
+ test_cmp expected actual
29
+'
30
+
31
+test_done
Godeps/_workspace/src/github.com/jbenet/go-multihash/test/test
Binary files a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/test and /dev/null differ