<commit_before>package org.mediachain.io


import cats.data.Xor
import org.mediachain.io.MultiHash.HashType


sealed abstract class MultiHashError
object MultiHashError {
  case class UnknownMultiHashType(message: String) extends MultiHashError
  case class InvalidHashLength(message: String) extends MultiHashError
  case class DecodingFailed(message: String) extends MultiHashError
}


object MultiHash {
  import java.security.MessageDigest
  import org.mediachain.io.MultiHashError._

  sealed abstract class HashType(val name: String, val index: Byte, val length: Byte)

  case object sha1 extends HashType("SHA-1", 0x11, 20)
  case object sha256 extends HashType("SHA-2 256", 0x12, 32)
  case object sha512 extends HashType("SHA-2 512", 0x13, 64)
  case object sha3 extends HashType("SHA-3", 0x14, 64)
  case object blake2b extends HashType("BLAKE2b", 0x40, 64)
  case object blake2s extends HashType("BLAKE2s", 0x41, 32)

  val lookup: Map[Byte, HashType] = Map[Byte, HashType](
    sha1.index -> sha1,
    sha256.index -> sha256,
    sha512.index -> sha512,
    sha3.index -> sha3,
    blake2b.index -> blake2b,
    blake2s.index -> blake2s
  )

  /**
    * Return a MultiHash of `contents` using SHA-256.
    * This is the IPFS default hash algorithm.
    *
    * @param contents an array of bytes to hash
    * @return a MultiHash describing the hashed contents
    */
  def usingSHA_256(contents: Array[Byte]): MultiHash = {
    val digest = MessageDigest.getInstance("SHA-256")

    // Creating a MultiHash from a valid SHA-256 digest should never fail,
    // so it seems like a decent candidate for an actual Exception
    fromHash(sha256, digest.digest(contents))
      .getOrElse(throw new IllegalStateException("Creation of SHA-256 MultiHash failed."))
  }


  def fromHash(hashType: HashType, hash: Array[Byte]): Xor[MultiHashError, MultiHash] = {
    if (hash.length > 127) {
      Xor.left(InvalidHashLength("MultiHash length must not exceed 127 bytes, but you gave me " +
        hash.length))
    } else if (hash.length != hashType.length) {
      Xor.left(InvalidHashLength("Hash type " + hashType.name + " has length of " +
        hashType.length + ", but you gave me " + hash.length))
    } else {
      Xor.right(new MultiHash(hashType, hash))
    }
  }


  def fromBytes(multihash: Array[Byte]): Xor[MultiHashError, MultiHash] = {
    val index = multihash(0)
    val hash = multihash.slice(1, multihash.length)<commit_msg>fix offset for MultiHash.fromBytes<commit_after>package org.mediachain.io


import cats.data.Xor
import org.mediachain.io.MultiHash.HashType


sealed abstract class MultiHashError
object MultiHashError {
  case class UnknownMultiHashType(message: String) extends MultiHashError
  case class InvalidHashLength(message: String) extends MultiHashError
  case class DecodingFailed(message: String) extends MultiHashError
}


object MultiHash {
  import java.security.MessageDigest
  import org.mediachain.io.MultiHashError._

  sealed abstract class HashType(val name: String, val index: Byte, val length: Byte)

  case object sha1 extends HashType("SHA-1", 0x11, 20)
  case object sha256 extends HashType("SHA-2 256", 0x12, 32)
  case object sha512 extends HashType("SHA-2 512", 0x13, 64)
  case object sha3 extends HashType("SHA-3", 0x14, 64)
  case object blake2b extends HashType("BLAKE2b", 0x40, 64)
  case object blake2s extends HashType("BLAKE2s", 0x41, 32)

  val lookup: Map[Byte, HashType] = Map[Byte, HashType](
    sha1.index -> sha1,
    sha256.index -> sha256,
    sha512.index -> sha512,
    sha3.index -> sha3,
    blake2b.index -> blake2b,
    blake2s.index -> blake2s
  )

  /**
    * Return a MultiHash of `contents` using SHA-256.
    * This is the IPFS default hash algorithm.
    *
    * @param contents an array of bytes to hash
    * @return a MultiHash describing the hashed contents
    */
  def usingSHA_256(contents: Array[Byte]): MultiHash = {
    val digest = MessageDigest.getInstance("SHA-256")

    // Creating a MultiHash from a valid SHA-256 digest should never fail,
    // so it seems like a decent candidate for an actual Exception
    fromHash(sha256, digest.digest(contents))
      .getOrElse(throw new IllegalStateException("Creation of SHA-256 MultiHash failed."))
  }


  def fromHash(hashType: HashType, hash: Array[Byte]): Xor[MultiHashError, MultiHash] = {
    if (hash.length > 127) {
      Xor.left(InvalidHashLength("MultiHash length must not exceed 127 bytes, but you gave me " +
        hash.length))
    } else if (hash.length != hashType.length) {
      Xor.left(InvalidHashLength("Hash type " + hashType.name + " has length of " +
        hashType.length + ", but you gave me " + hash.length))
    } else {
      Xor.right(new MultiHash(hashType, hash))
    }
  }


  def fromBytes(multihash: Array[Byte]): Xor[MultiHashError, MultiHash] = {
    val index = multihash(0)
    val hash = multihash.slice(2, multihash.length)
{'fraction_non_alphanumeric': 0.1013609587649807, 'fraction_numerical': 0.0398131220800325, 'mean_word_length': 3.693994280266921, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, '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': '2138864', 'n_tokens_mistral': 1692, 'n_tokens_neox': 1528, 'n_words': 464}