简体   繁体   中英

How to generate 15 digit random number using Scala

I am new to Scala programming, I want to generate random number with 15 digits, So can you please let share some example. I have tried the below code to get the alpha number string with 10 digits.

  var ranstr = s"${(Random.alphanumeric take 10).mkString}"
  print("ranstr", ranstr)

You need to pay attention to the return type. You cannot have a 15-digit Int because that type is a 32-bit signed integer, meaning that it's maximum value is a little over 2B. Even getting a 10-digit number means you're at best getting a number between 1B and the maximum value of Int .

Other answers go in the detail of how to get a 15-digits number using Long . In your comment you mentioned between , but because of the limitation I mentioned before, using Int s will not allow you to go beyond the 9 digits in your example. You can, however, explicitly annotate your numeric literals with a trailing L to make them Long and achieve what you want as follows:

Random.between(100000000000000L, 1000000000000000L)

Notice that the documentation for between says that the last number is exclusive.

If you're interested in generating arbitrarily large numbers, a String might get the job done, as in the following example:

import scala.util.Random
import scala.collection.View

def nonZeroDigit: Char = Random.between(49, 58).toChar
def digit: Char = Random.between(48, 58).toChar

def randomNumber(length: Int): String = {
  require(length > 0, "length must be strictly positive")
  val digits = View(nonZeroDigit) ++ View.fill(length - 1)(digit)
  digits.mkString
}

randomNumber(length = 1)
randomNumber(length = 10)
randomNumber(length = 15)
randomNumber(length = 40)

Notice that when converting an Int to a Char what you get is the character encoded by that number, which isn't necessarily the same as the digit represented by the Int itself. The numbers you see in the functions from the ASCII table (odds are it's good enough for what you want to do).

If you really need a numeric type, for arbitrarily large integers you will need to use BigInt . One of its constructors allows you to parse a number from a string, so you can re-use the code above as follows:

import scala.math.BigInt

BigInt(randomNumber(length = 15))
BigInt(randomNumber(length = 40))

You can play around with this code here on Scastie .

Notice that in my example, in order to keep it simple, I'm forcing the first digit of the random number to not be zero. This means that the number 0 itself will never be a possible output. If you want that to be the case if one asks for a 1-digit long number, you're advised to tailor the example to your needs.

A similar approach to that by Alin's foldLeft , based here in scanLeft , where the intermediate random digits are first collected into a Vector and then concatenated as a BigInt , while ensuring the first random digit (see initialization value in scanLeft ) is greater than zero,

import scala.util.Random
import scala.math.BigInt

def randGen(n: Int): BigInt = {
    val xs = (1 to n-1).scanLeft(Random.nextInt(9)+1) { 
        case (_,_) => Random.nextInt(10) 
    }
    BigInt(xs.mkString)
}

To notice that Random.nextInt(9) will deliver a random value between 0 and 8 , thus we add 1 to shift the possibble values from 1 to 9 . Thus,

scala> (1 to 15).map(randGen(_)).foreach(println)
8
34
623
1597
28474
932674
5620336
66758916
186155185
2537294343
55233611616
338190692165
3290592067643
93234908948070
871337364826813

In scala we have scala.util.Random to get a random value (not only numeric), for a numeric value random have nextInt(n: Int) what return a random num < n. Read more about random

First example:

    val random = new Random()
    val digits = "0123456789".split("")
    var result = ""
    for (_ <- 0 until 15) {
      val randomIndex = random.nextInt(digits.length)
      result += digits(randomIndex)
    }
    println(result)

Here I create an instance of random and use a number from 0 to 9 to generate a random number of length 15

Second example:

    val result2 = for (_ <- 0 until 15) yield random.nextInt(10)
    println(result2.mkString)

Here I use the yield keyword to get an array of random integers from 0 to 9 and use mkString to combine the array into a string. Read more about yield

There a lot of ways to do this.

The most common way is to use Random.nextInt(10) to generate a digit between 0-9. When building a number of a fixed size of digits, you have to make sure the first digit is never 0.

For that I'll use Random.nextInt(9) + 1 which guaranteees generating a number between 1-9 and a sequence with the other 14 generated digits, and a foldleft operation with the first digit as accumulator to generate the number:

  val number =
    Range(1, 15).map(_ => Random.nextInt(10)).foldLeft[Long](Random.nextInt(9) + 1) {
      (acc, cur_digit) => acc * 10 + cur_digit
    }

Normally for such big numbers it's better to represent them as sequence of characters instead of numbers because numbers can easily overflow. But since a 15 digit number fits in a Long and you asked for a number, I used one instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM