All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ulid.Rnd.scala Maven / Gradle / Ivy

The newest version!
package ulid

import java.security.SecureRandom
import java.util.{Random, UUID}
import java.util.concurrent.atomic.AtomicInteger

import scala.annotation.tailrec


trait Rnd extends {

  def set(buf: Array[Char], offset: Int): Unit
}

object Rnd {

  def make(f:  => (Long, Long)): Rnd = new Rnd {

    override def set(buf: Array[Char], offset: Int): Unit = {
      val (less, most) = f

      @tailrec def setChar(i: Int = 0): Unit = if (i < 16) {
        val b = if (i < 8) {
          ((less >> (i * 8)) & 0xFF).toByte
        } else {
          ((most >> ((i - 8) * 8)) & 0xFF).toByte
        }

        buf(offset + i) = Crockford.EncodeChars(b + 128)
        setChar(i + 1)
      }

      setChar()
    }
  }

  lazy val fastWeakSeed: Rnd = {
    val rnd = new Random()
    val nodeId = rnd.nextInt.toLong
    val seed = new AtomicInteger(rnd.nextInt)
    make {
      (nodeId << 16 | seed.incrementAndGet, System.nanoTime)
    }
  }

  lazy val fastSecureSeed: Rnd = {
    val rnd = SecureRandom.getInstance("NativePRNGNonBlocking")
    val nodeId = rnd.nextInt.toLong
    val seed = new AtomicInteger(rnd.nextInt)
    make {
      (nodeId << 16 | seed.incrementAndGet, System.nanoTime)
    }
  }

  lazy val uuid: Rnd = {
    make {
      val uuid = UUID.randomUUID()

      (uuid.getLeastSignificantBits, uuid.getMostSignificantBits)
    }
  }

  lazy val weak: Rnd = {
    val r = new Random()
    make {
      (r.nextLong(), r.nextLong())
    }
  }

  lazy val secure: Rnd = {
    val r = SecureRandom.getInstance("NativePRNGNonBlocking")
    make {
      (r.nextLong(), r.nextLong())
    }
  }

  lazy val default: Rnd = lookupDefault(sys.props)

  private[ulid] def lookupDefault(props: collection.Map[String, String]): Rnd = {
    props.getOrElse("ulid.rnd", "fastWeakSeed") match {
      case "weak"           => weak
      case "secure"         => secure
      case "uuid"           => uuid
      case "fastSecureSeed" => fastSecureSeed
      case "fastWeakSeed"   => fastWeakSeed
      case _                => fastWeakSeed
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy