Kuina-chan

くいなちゃん2018年12月11日


プログラミング言語Kuin」の逆引き辞典8、乱数と時間と暗号の扱い方についてです。

目次

1乱数を扱う

Kuinの疑似乱数生成にはメルセンヌツイスタ(SFMT)を用いていて、周期の高品質な擬似乱数が高速で生成されます。

1.1再現性のない乱数を取得する



プログラムを起動するたびに異なる乱数を生成したい場合には、「lib@rnd」「lib@rndFloat」「lib@rndBit64」を使います(図1-1)。
  1. func main()
  2.   var i: int :: lib@rnd(3, 8) {3以上8以下の整数の乱数}
  3.   var f: float :: lib@rndFloat(3.0, 8.0) {3.0以上8.0未満の小数の乱数}
  4.   var b: bit64 :: lib@rndBit64() {0以上0xFFFFFFFFFFFFFFFF以下の乱数}
  5. end func
図1-1: 再現性のない乱数の取得

1.2再現性のある乱数を取得する



同じ乱数列を生成したい場合には、「lib@makeRnd」を使います(図1-2)。
  1. func main()
  2.   var rnd: lib@Rnd :: lib@makeRnd(1234) {乱数のシード値を指定}
  3.   var i: int :: rnd.rnd(3, 8) {6}
  4.   var f: float :: rnd.rndFloat(3.0, 8.0) {6.13495}
  5.   var b: bit64 :: rnd.rndBit64() {0xBE10B479E4D166ED}
  6. end func
図1-2: 再現性のある乱数の取得
lib@makeRndの引数に渡した値によって、生成される乱数列が決まります。

1.3UUIDを生成する



「00000000-0000-4000-8000-000000000000」のような36文字のユニークな文字列「UUIDバージョン4」を生成するには、「lib@rndUuid」を使います(図1-3)。
  1. func main()
  2.   var uuid: []char :: lib@rndUuid()
  3. end func
図1-3: UUIDの生成
生成したUUIDのいずれか2つが偶然重複するには、期待値で約(=約230京)個生成する必要があり、現実には起こらないものとみなせます。

2時間を扱う

2.1現在時刻を取得する



現在時刻を取得するには「lib@now」を使います。 ただしUNIX時間(1970年1月1日0時0分0秒からの経過時間を秒で表した値)で返ってくるため、適宜「lib@intToDate」「lib@intToLocalDate」で、年月日時分秒を取得します(図2-1)。
  1. func main()
  2.   var unixTime: int
  3.   var year: int {年(西暦4桁)}
  4.   var month: int {月(1以上12以下)}
  5.   var day: int {日(1以上31以下)}
  6.   var hour: int {時(0以上23以下)}
  7.   var minute: int {分(0以上59以下)}
  8.   var second: int {秒(0以上59以下)}
  9.   var day_of_week: int {曜日(0=日、1=月、…、6=土)}
  10.  
  11.   do unixTime :: lib@now()
  12.   do day_of_week :: lib@intToDate(unixTime, &year, &month, &day, &hour, &minute, &second)
  13.   do unixTime :: lib@dateToInt(year, month, day, hour, minute, second)
  14.  
  15.   do unixTime :: lib@now()
  16.   do day_of_week :: lib@intToLocalDate(unixTime, &year, &month, &day, &hour, &minute, &second)
  17.   do unixTime :: lib@localDateToInt(year, month, day, hour, minute, second)
  18. end func
図2-1: 現在時刻の取得
「intToDate」はUNIX時間をUTC(協定世界時)での日付に変換し、「intToLocalDate」は実行環境ごとに設定されたタイムゾーンのローカルな日付に変換します。
逆に「dateToInt」「localDateToInt」はそれぞれ、UTCでの日付やローカルな日付をUNIX時間に変換します。

2.2一定時間待つ



一定時間処理を停止させるには「lib@sleep(待機時間(ミリ秒))」とします(図2-2)。
  1. func main()
  2.   do lib@sleep(1000) {1秒間待機}
  3. end func
図2-2: 処理の待機

2.3経過時間を計測する



ある時点からの経過時間を得るには、「lib@sysTime」を使います。 lib@sysTimeはOSが起動してから現在までに経った時間がミリ秒で返るため、差分を計算することで経過時間が判ります(図2-3)。
  1. func main()
  2.   var before: int :: lib@sysTime()
  3.   do lib@sleep(1000)
  4.   var after: int :: lib@sysTime()
  5.   var time: int :: after - before {経過時間(ミリ秒)}
  6. end func
図2-3: 経過時間の計測

3暗号を扱う

(この記事は執筆中です!)
1544537936jaf