3

Swift 3 を使用して Linux でランダムな文字列を生成しようとすると、2 つの問題が発生します。

  1. arc4random_uniform は、Linux では BSD のみで使用できません。SO私はrandom()関数を使用して逃げることができました。そして、これは可変サイズの乱数を生成していたときに機能しました(以下のコードを参照)

    func generateRandomNumber() -> Int
    {
       var place = 1
    
       var finalNumber = 0;
    
    #if os(Linux)
    for _ in 0..<5
    {
        place *= 10
    
        let randomNumber = Int(random() % 10) + 1
    
        finalNumber += randomNumber * place
    }
    #else
    for _ in 0..<5
    {
        place *= 10
    
        let randomNumber = Int(arc4random_uniform(10))
    
        finalNumber += randomNumber * place
    }
    #endif
    
      return finalNumber
    }
    

そして、それはうまくいきます。 編集:動作しますが、毎回同じ番号が表示されます:(

  1. ランダムな英数字の文字列を生成しようとすると、Swift String の使用に制限され、NSSTRING は使用されません。Linux はこのエラーをスローします

元の Linux 以前のコード ブロック:

   func randomString(_ length: Int) -> String
   {

      let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
      let len = UInt32(letters.length)

      var randomString = ""

      for _ in 0 ..< length {
    let rand = arc4random_uniform(len)
    var nextChar = letters.character(at: Int(rand))
    randomString += NSString(characters: &nextChar, length: 1) as String
      }

       return randomString
    }

上記のコードを使用したときに実際に発生するエラー

    error: cannot convert value of type 'NSString' to type 'String' in coercion
        randomString += NSString(characters: &nextChar, length: 1) as String

コードの Linux ブロック用に変更されました。

    func randomString(_ length: Int) -> String
    {

let letters : String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let len = letters.characters.count

var randomString = ""

#if os(Linux)

    for _ in 0..<length
    {
        let randomValue = (random() % len) + 1

        randomString += "\(letters[letters.index(letters.startIndex, offsetBy: Int(randomValue))])"
    }

    #else
    for _ in 0 ..< length
    {
        let rand = arc4random_uniform(UInt32(len))

        randomString += "\(letters[letters.index(letters.startIndex, offsetBy: Int(rand))])"
    }
    #endif


      return randomString
}          

しかし、今回のエラーは奇妙で 、追加情報なしでIllegal instructionとだけ表示されます。docker コンテナをインタラクティブ モードで実行したところ、他の関数などを呼び出すときにサーバーが実行され、出力されるのを見ました。

しかし、問題は、IBMの迅速なサンドボックスで実行したときに実際に機能する機能です

ここに画像の説明を入力 また、Linuxも使用していると想定しています。私は非常に行き詰まり、混乱しています。どんな助けでも大歓迎です。

(更新): Vapor の迅速な Web フレームワークではなく、単一の迅速なファイルを使用して、Linux 環境で同じ機能を実行しました。そしてそれは動作します。上記の編集で述べたように、毎回同じランダムな文字列が返されます。ビルドが完了したら、プロジェクト全体をテストする必要があります。しかし、それ以外にも、 random() 関数が実際に毎回同じがらくたではなく新しい何かを与えるかどうかを知る必要があります。

4

4 に答える 4

3

1) 常に同じ番号

から「乱数」を取得するには、シードを一度設定する必要がありますrandom()

randomSeed(Int(Date().timeIntervalSince1970)

マニュアルページ:

シード値が指定されていない場合、random() 関数は自動的に値 1 でシードされます。

シードは常に同じ (1) であるため、常に同じ一連の「乱数」が得られます。

2) 英数字文字列

を使用せずに文字列を作成するにはNSString:

func randomString(length: Int) -> String {

    let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    let len = UInt32(letters.characters.count)

    var randomString = ""

    for _ in 0 ..< length {
        let rand = myCustomRandom(len)
        let randIndex = letters.index(letters.startIndex, offsetBy: Int(rand))
        let nextChar = letters[randIndex]
        randomString += String(nextChar)
    }

    return randomString
}
于 2017-01-08T07:57:28.070 に答える
3

理解した。

したがって、乱数/文字列の繰り返しに対する答えは、 random() 関数を呼び出す前にこの行を追加することでした

srand(UInt32(time(nil)))

そして、それが違法な命令も修正したと思います。他に何かを変えた覚えがないからです。

言うまでもなく、これが私の最終結果です

 func generateRandomNumber() -> Int
 {
    var place = 1

    var finalNumber = 0;

    #if os(Linux)

    srand(UInt32(time(nil)))

    for _ in 0..<5
    {
        place *= 10

        let randomNumber = Int(random() % 10) + 1

        finalNumber += randomNumber * place
    }
    #else
    for _ in 0..<5
    {
        place *= 10

        let randomNumber = Int(arc4random_uniform(10))

        finalNumber += randomNumber * place
    }
    #endif

     return finalNumber
 }



 func randomString(_ length: Int) -> String
 {

    let letters : String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    let len = letters.characters.count

    var randomString = ""

    #if os(Linux)

    srand(UInt32(time(nil)))

   for _ in 0..<length
   {
     let randomValue = (random() % len) + 1

     randomString += "\(letters[letters.index(letters.startIndex, offsetBy: Int(randomValue))])"
   }

   #else
  for _ in 0 ..< length
  {
     let rand = arc4random_uniform(UInt32(len))

     randomString += "\(letters[letters.index(letters.startIndex, offsetBy: Int(rand))])"
  }
  #endif

   return randomString
 }  
于 2017-01-08T08:00:39.430 に答える