简体   繁体   English

如何使用 Scala 生成 15 位随机数

[英]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.我是 Scala 编程的新手,我想生成 15 位的随机数,所以请你分享一些例子。 I have tried the below code to get the alpha number string with 10 digits.我尝试了以下代码来获取 10 位的字母数字字符串。

  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.您不能有 15 位Int ,因为该类型是 32 位带符号的 integer,这意味着它的最大值略高于 2B。 Even getting a 10-digit number means you're at best getting a number between 1B and the maximum value of Int .即使获得一个 10 位数字也意味着您最多只能获得一个介于 1B 和Int最大值之间的数字。

Other answers go in the detail of how to get a 15-digits number using Long .其他答案 go 详细介绍了如何使用Long获取 15 位数字。 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.在您提到的评论between ,但由于我之前提到的限制,使用Int s 将不允许您 go 超出示例中的 9 位数字。 You can, however, explicitly annotate your numeric literals with a trailing L to make them Long and achieve what you want as follows:但是,您可以使用尾随L显式注释您的数字文字,以使其为Long并实现您想要的内容,如下所示:

Random.between(100000000000000L, 1000000000000000L)

Notice that the documentation for between says that the last number is exclusive.请注意, between的文档说最后一个数字是排他的。

If you're interested in generating arbitrarily large numbers, a String might get the job done, as in the following example:如果您对生成任意大的数字感兴趣, String可能会完成这项工作,如下例所示:

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.请注意,将Int转换为Char时,您得到的是由该数字编码的字符,它不一定与Int本身表示的数字相同。 The numbers you see in the functions from the ASCII table (odds are it's good enough for what you want to do).您在ASCII 表中的函数中看到的数字(很可能对于您想要做的事情来说已经足够好了)。

If you really need a numeric type, for arbitrarily large integers you will need to use BigInt .如果您确实需要数字类型,对于任意大的整数,您将需要使用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 .您可以在 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.这意味着数字 0 本身永远不会是可能的 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.如果您希望在要求 1 位长号码时出现这种情况,建议您根据需要定制示例。

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,与 Alin 的foldLeft类似的方法,基于scanLeft ,其中中间随机数字首先被收集到Vector中,然后连接为BigInt ,同时确保第一个随机数字(参见scanLeft中的初始化值)大于零,

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 .要注意Random.nextInt(9)将提供一个介于08之间的随机值,因此我们添加1可能的值从1转移到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.在 scala 中,我们有scala.util.Random来获取随机值(不仅是数字),对于数值随机有nextInt(n: Int)返回随机 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这里我创建了一个 random 的实例,并使用一个从 0 到 9 的数字来生成一个长度为 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.这里我使用yield关键字来获取一个从0到9的随机整数数组,并使用mkString将数组组合成一个字符串。 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.最常见的方法是使用Random.nextInt(10)生成 0-9 之间的数字。 When building a number of a fixed size of digits, you have to make sure the first digit is never 0.在构建固定大小的数字时,必须确保第一个数字永远不会为 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:为此,我将使用Random.nextInt(9) + 1来保证生成 1-9 之间的数字和具有其他 14 个生成数字的序列,并使用第一个数字作为累加器的foldleft操作来生成数字:

  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.但是由于一个 15 位数字适合Long并且您要求一个数字,所以我使用了一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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