func GetByteArrayHash(bytes []byte) int {
	return int(murmur.MurmurHash2(computeNormalizedArray(bytes), 1))
}
Credit goes to modmuss https://github.com/modmuss50/CAV2/blob/master/murmur.go
package main
import (
	"archive/zip"
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/aviddiviner/go-murmur"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"
)
func readBuildJson(buildJsonDir string) (buildJson) {
	jsonFile, err := os.Open(buildJsonDir)
	if err != nil {
		fmt.Println(err)
	}
	defer jsonFile.Close()
	byteValue, _ := ioutil.ReadAll(jsonFile)
	var buildCfg buildJson
	json.Unmarshal(byteValue, &buildCfg)
	return buildCfg
}
func intInSlice(a int, list []int) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}
func CopyFile(src, dst string) error {
	var err error
	var srcfd *os.File
	var dstfd *os.File
	var srcinfo os.FileInfo
	if srcfd, err = os.Open(src); err != nil {
		return err
	}
	defer srcfd.Close()
	if dstfd, err = os.Create(dst); err != nil {
		return err
	}
	defer dstfd.Close()
	if _, err = io.Copy(dstfd, srcfd); err != nil {
		return err
	}
	if srcinfo, err = os.Stat(src); err != nil {
		return err
	}
	return os.Chmod(dst, srcinfo.Mode())
}
func CopyDir(src string, dst string) error {
	var err error
	var fds []os.FileInfo
	var srcinfo os.FileInfo
	if srcinfo, err = os.Stat(src); err != nil {
		return err
	}
	if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
		return err
	}
	if fds, err = ioutil.ReadDir(src); err != nil {
		return err
	}
	for _, fd := range fds {
		srcfp := path.Join(src, fd.Name())
		dstfp := path.Join(dst, fd.Name())
		if fd.IsDir() {
			if err = CopyDir(srcfp, dstfp); err != nil {
				fmt.Println(err)
			}
		} else {
			if err = CopyFile(srcfp, dstfp); err != nil {
				fmt.Println(err)
			}
		}
	}
	return nil
}
func Difference(a, b []int) (diff []int) {
	m := make(map[int]bool)
	for _, item := range b {
		m[item] = true
	}
	for _, item := range a {
		if _, ok := m[item]; !ok {
			diff = append(diff, item)
		}
	}
	return
}
func RecursiveZip(pathToZip, destinationPath string) error {
	destinationFile, err := os.Create(destinationPath)
	if err != nil {
		return err
	}
	myZip := zip.NewWriter(destinationFile)
	err = filepath.Walk(pathToZip, func(filePath string, info os.FileInfo, err error) error {
		if info.IsDir() {
			fmt.Println("info.IsDir is Nil")
			return nil
		}
		if err != nil {
			fmt.Println("FilePath walk error")
			return err
		}
		relPath := strings.TrimPrefix(filepath.ToSlash(filePath), filepath.Base(pathToZip)+"/")
		zipFile, err := myZip.Create(relPath)
		if err != nil {
			fmt.Println("Creating zip error")
			return err
		}
		fsFile, err := os.Open(filePath)
		if err != nil {
			fmt.Println("os.Open error")
			return err
		}
		defer fsFile.Close()
		_, err = io.Copy(zipFile, fsFile)
		if err != nil {
			fmt.Println("io.copy error")
			return err
		}
		return nil
	})
	if err != nil {
		fmt.Println("File path walk error ln151")
		return err
	}
	err = myZip.Close()
	if err != nil {
		fmt.Println("Close zip error")
		return err
	}
	return nil
}
func RemoveContents(dir string) error {
	d, err := os.Open(dir)
	if err != nil {
		return err
	}
	defer d.Close()
	names, err := d.Readdirnames(-1)
	if err != nil {
		return err
	}
	for _, name := range names {
		err = os.RemoveAll(filepath.Join(dir, name))
		if err != nil {
			return err
		}
	}
	return nil
}
func getProjectIds(addons []int) (*fingerprintResponse, error) {
	jsonPayload, _ := json.Marshal(addons)
	response, err := GetHTTPResponse("POST", ApiUrl+"fingerprint", jsonPayload)
	if err != nil {
		return nil, err
	}
	var addonResponse *fingerprintResponse
	err = json.NewDecoder(response.Body).Decode(&addonResponse)
	if err != nil {
		return nil, err
	}
	return addonResponse, nil
}