3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Ruby]fakerでランダムなBitcoinアドレスが生成できるようになってた件(あとアニメキャラも)

Posted at

はじめに

Rubyにはランダムなダミーデータを生成してくれる、fakerというGemがあります。
テストデータとして、既に利用している方も多いかと思います。

例えば、これだけでランダムな名前が自動生成できちゃいます。
(デフォルトはlocaleがenなので外人さんの名前)

require 'faker'

Faker::Name.name
# => "Christophe Bartell"

ビットコインアドレスも自動生成できる

fakerのGitHubを見ていたら偶然、Blockchainというカテゴリを発見。
気になったので内部を拝見すると、どうやら以下のアドレスを自動生成できるようです。

  • bitcoin
  • ethereum
  • tezos(なぜw)

そしてGitHubを見る限り、このbitcoinはlocalesのymlファイルを参照しているわけはなく、それぞれRubyのロジックでランダムな値を生成していることが分かります。

ビットコインアドレスの生成手順

補足として、ビットコインアドレスの生成手順をざっくり纏めると、概ね以下の通りです。
だいたいの雰囲気が分かればとりあえずOKです。

  1. 公開鍵をSHA256とRIPEMID160で二重ハッシュ化する、これをPayloadと呼ぶ。
  2. Payload先頭にversion prefixを付与する
  3. 上記の値をSHA256で2回ハッシュ化し、そこから先頭の4バイトを取得して最後尾に付与する
  4. 上記の値をBase 58エンコードする

これでビットコインアドレスの完成です。

fakerのコードを覗いてみる

上記の手順を念頭にGitHubのコードを覗いてみます。
コード量がそれほど多くないのでコピペします。

# frozen_string_literal: true

require 'digest'
require 'securerandom'

module Faker
  class Blockchain
    class Bitcoin < Base
      class << self
        PROTOCOL_VERSIONS = {
          main: 0,
          testnet: 111
        }.freeze

        def address
          address_for(:main)
        end

        def testnet_address
          address_for(:testnet)
        end

        protected

        def address_for(network)
          version = PROTOCOL_VERSIONS.fetch(network)
          packed = version.chr + Faker::Config.random.bytes(20)
          checksum = Digest::SHA2.digest(Digest::SHA2.digest(packed))[0..3]
          Faker::Base58.encode(packed + checksum)
        end
      end
    end
  end
end

def address_forがビットコインアドレスを生成している処理です。
Faker::Config.random.bytes(20)が、手順1のPayloadを想定していると思われます。
その後の処理も読み解くと、fakerはそれなりにビットコインアドレスの生成手順に沿って値を生成していることが分かります。
実際は公開鍵のハッシュ値を参照してるわけではないので、それっぽいアドレスですがビットコインの送受信はできないはずです。

さいごに

余談ですが、Blockchain以外でも偶然「Japanese Media」というカテゴリを発見しました。
内容を見ると、

  • dragon_ball
  • one_piece
  • sword_art_online(なぜw)

今時点で、この3種が用意されてました。
ソードアートオンラインは議論を呼びそうですが、これもコミッターの特権ということで。

dragon_ballだと、キャラの名前だけがランダムに取得できるようです。

Faker::JapaneseMedia::DragonBall.character
# => "Goku"

名前が定義されたymlはlocales/en配下にあるので、localeがenの場合のみ利用できると思われます(試してない)。

そしてワンピースだと、キャラの名前以外にもいろいろな値が自動生成できるようです。
(ドラゴンボールとはえらい違いだ)

Faker::JapaneseMedia::OnePiece.character #=> "Monkey D. Luffy"
Faker::JapaneseMedia::OnePiece.sea #=> "East Blue"
Faker::JapaneseMedia::OnePiece.island #=> "Laftel"
Faker::JapaneseMedia::OnePiece.location #=> "Foosha Village"
Faker::JapaneseMedia::OnePiece.quote #=> "ONE PIECE IS REAL!"
Faker::JapaneseMedia::OnePiece.akuma_no_mi #=> "Gomu Gomu no Mi"

それにしてもこのfakerの使い道がよく分かりませんね。
完全にネタな気がしますが、こうして日本の文化が採用されることを誇りに思いましょうw

以上、読んで頂きありがとうございました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?