<commit_before>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package common

import (
	"bytes"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/hex"
	"fmt"
)

type Hash struct {
	bytes [HASH_LENGTH]byte `json:"bytes"`
}

func (h *Hash) Bytes() []byte {
	return h.GetBytes()
}

func NewHash() *Hash {
	h := new(Hash)
	return h
}

func CreateHash(entities ...BinaryMarshallable) (h *Hash, err error) {
	sha := sha256.New()
	h = new(Hash)
	for _, entity := range entities {
		data, err := entity.MarshalBinary()
		if err != nil {
			return nil, err
		}
		sha.Write(data)
	}
	copy(h.bytes[:], sha.Sum(nil))
	return
}

func (h *Hash) MarshalBinary() ([]byte, error) {
	var buf bytes.Buffer
	buf.Write(h.bytes[:])
	return buf.Bytes(), nil
}

func (h *Hash) UnmarshalBinary(p []byte) error {
	copy(h.bytes[:], p)
	return nil
}

func (h *Hash) GetBytes() []byte {
	newHash := make([]byte, HASH_LENGTH)
	copy(newHash, h.bytes[:])

	return newHash
}

// SetBytes sets the bytes which represent the hash.  An error is returned if
// the number of bytes passed in is not HASH_LENGTH.
func (hash *Hash) SetBytes(newHash []byte) error {
	nhlen := len(newHash)
	if nhlen != HASH_LENGTH {
		return fmt.Errorf("invalid sha length of %v, want %v", nhlen, HASH_LENGTH)
	}

	copy(hash.bytes[:], newHash)
	return nil
}

// NewShaHash returns a new ShaHash from a byte slice.  An error is returned if
// the number of bytes passed in is not HASH_LENGTH.
func NewShaHash(newHash []byte) (*Hash, error) {
	var sh Hash
	err := sh.SetBytes(newHash)
	if err != nil {
		return nil, err
	}
	return &sh, err
}

// Create a Sha256 Hash from a byte array
func Sha(p []byte) (h *Hash) {
	sha := sha256.New()
	sha.Write(p)

	h = new(Hash)
	copy(h.bytes[:], sha.Sum(nil))
	return h
}

// Create a Sha512[:256] Hash from a byte array
func Sha512Half(p []byte) (h *Hash) {
	sha := sha512.New()
	sha.Write(p)

	h = new(Hash)
	copy(h.bytes[:], sha.Sum(nil)[:256])
	return h
}

// Convert a hash into a string with hex encoding
func (h *Hash) String() string {
	if h == nil {
		return hex.EncodeToString(nil)
	} else {
		return hex.EncodeToString(h.bytes[:])
	}
}

func (h *Hash) ByteString() string {
	return string(h.bytes[:])
}

func HexToHash(hexStr string) (h *Hash, err error) {
	h = new(Hash)
	v, err := hex.DecodeString(hexStr)
	err = h.SetBytes(v)
	return h, err
}

// String returns the ShaHash in the standard bitcoin big-endian form.
func (h *Hash) BTCString() string {
	hashstr := ""
	hash := h.bytes
	for i := range hash {
		hashstr += fmt.Sprintf("%02x", hash[HASH_LENGTH-1-i])
	}
<commit_msg>Fixed the SHA slice out of bounds<commit_after>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package common

import (
	"bytes"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/hex"
	"fmt"
)

type Hash struct {
	bytes [HASH_LENGTH]byte `json:"bytes"`
}

func (h *Hash) Bytes() []byte {
	return h.GetBytes()
}

func NewHash() *Hash {
	h := new(Hash)
	return h
}

func CreateHash(entities ...BinaryMarshallable) (h *Hash, err error) {
	sha := sha256.New()
	h = new(Hash)
	for _, entity := range entities {
		data, err := entity.MarshalBinary()
		if err != nil {
			return nil, err
		}
		sha.Write(data)
	}
	copy(h.bytes[:], sha.Sum(nil))
	return
}

func (h *Hash) MarshalBinary() ([]byte, error) {
	var buf bytes.Buffer
	buf.Write(h.bytes[:])
	return buf.Bytes(), nil
}

func (h *Hash) UnmarshalBinary(p []byte) error {
	copy(h.bytes[:], p)
	return nil
}

func (h *Hash) GetBytes() []byte {
	newHash := make([]byte, HASH_LENGTH)
	copy(newHash, h.bytes[:])

	return newHash
}

// SetBytes sets the bytes which represent the hash.  An error is returned if
// the number of bytes passed in is not HASH_LENGTH.
func (hash *Hash) SetBytes(newHash []byte) error {
	nhlen := len(newHash)
	if nhlen != HASH_LENGTH {
		return fmt.Errorf("invalid sha length of %v, want %v", nhlen, HASH_LENGTH)
	}

	copy(hash.bytes[:], newHash)
	return nil
}

// NewShaHash returns a new ShaHash from a byte slice.  An error is returned if
// the number of bytes passed in is not HASH_LENGTH.
func NewShaHash(newHash []byte) (*Hash, error) {
	var sh Hash
	err := sh.SetBytes(newHash)
	if err != nil {
		return nil, err
	}
	return &sh, err
}

// Create a Sha256 Hash from a byte array
func Sha(p []byte) (h *Hash) {
	sha := sha256.New()
	sha.Write(p)

	h = new(Hash)
	copy(h.bytes[:], sha.Sum(nil))
	return h
}

// Create a Sha512[:256] Hash from a byte array
func Sha512Half(p []byte) (h *Hash) {
	sha := sha512.New()
	sha.Write(p)

	h = new(Hash)
	copy(h.bytes[:], sha.Sum(nil)[:32])
	return h
}

// Convert a hash into a string with hex encoding
func (h *Hash) String() string {
	if h == nil {
		return hex.EncodeToString(nil)
	} else {
		return hex.EncodeToString(h.bytes[:])
	}
}

func (h *Hash) ByteString() string {
	return string(h.bytes[:])
}

func HexToHash(hexStr string) (h *Hash, err error) {
	h = new(Hash)
	v, err := hex.DecodeString(hexStr)
	err = h.SetBytes(v)
	return h, err
}

// String returns the ShaHash in the standard bitcoin big-endian form.
func (h *Hash) BTCString() string {
	hashstr := ""
	hash := h.bytes
	for i := range hash {
		hashstr += fmt.Sprintf("%02x", hash[HASH_LENGTH-1-i])
	}

{'fraction_non_alphanumeric': 0.14937136423343966, 'fraction_numerical': 0.0136986301369863, 'mean_word_length': 3.6795434591747145, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6908610', 'n_tokens_mistral': 2064, 'n_tokens_neox': 1970, 'n_words': 644}