blob: bb424d486b1669655eb7e25bc03f05f9927f84d4 [file] [log] [blame]
// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package sha256key provides access to the hash function used to make content-addressable keys.
package sha256key // import "upspin.io/key/sha256key"
import (
"crypto/sha256"
"fmt"
"upspin.io/errors"
)
var (
errHashFormat = errors.Str("bad hash format")
)
// Size is the number of bytes in a hash.
const Size = sha256.Size
// ZeroHash is the zero-valued hash.
var ZeroHash Hash
// Hash represents a SHA-256 hash code. It is always 32 bytes long.
// Its representation is an array so it can be treated as a value.
type Hash [Size]byte // SHA-256 hash always 32 bytes
// String returns a hexadecimal representation of the hash.
func (hash Hash) String() string {
return BytesString(hash[:])
}
// BytesString returns a string representation of the hash that is represented in bytes.
func BytesString(hash []byte) string {
return fmt.Sprintf("%X", hash)
}
// EqualString compares the byte-level representation of a hash with its hex string representation,
// avoiding allocation.
func (hash Hash) EqualString(b string) bool {
h, err := Parse(b)
return err == nil && h == hash
}
// Parse returns the hash whose standard format (possibly absent the brackets) is the value of str.
func Parse(str string) (hash Hash, err error) {
err = errHashFormat
if len(str) != 2*Size {
return
}
for i := range hash {
a := unhex(str[2*i])
b := unhex(str[2*i+1])
if a == 255 || b == 255 {
return
}
hash[i] = a<<4 | b
}
err = nil
return
}
// unhex returns the value of the hex nibble or 255 if it's bad.
func unhex(b uint8) uint8 {
switch {
case '0' <= b && b <= '9':
return b - '0'
case 'a' <= b && b <= 'f':
return 10 + b - 'a'
case 'A' <= b && b <= 'F':
return 10 + b - 'A'
}
return 255
}
// Of returns the SHA-256 hash of the data, as a Hash.
// The odd name works well in the client: sha256key.Of.
func Of(data []byte) (hash Hash) {
return sha256.Sum256(data)
}