# Splits a mnemonic phrase into several cards. When a card is found, not all of # the words are known. This increases security. The program is written in Ruby. # It asks for the phrase and the number of cards during runtime. The phrase is # never sent (to any servers). It is not a malicious program. Since the source # code is open source and free, this can be verified. # Copyright (c) 2021 Marek Küthe # This work is free. You can redistribute it and/or modify it under the # terms of the Do What The Fuck You Want To Public License, Version 2, # as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. require "securerandom" print "Number of cards: " STDOUT.flush n_cards = gets.chomp.to_i print "Phase: " STDOUT.flush phase = gets.chomp.split pick_words = [] words_per_cards = phase.length / n_cards remaining_words = phase.length % n_cards # Random sorting of words; The words are treated as numbers for i in 0...(phase.length) loop do pick_words[i] = SecureRandom.rand(0...(phase.length)) break if ! pick_words[0...-1].include? pick_words[i] end end # p pick_words cards = [] for i in 0...n_cards # Adding the number of words to each card # Number = number of words / number of cards cards[i] = pick_words[(i*words_per_cards)...((i+1)*words_per_cards)] # It can happen that this calculation does not always work out. The remaining # words are added to the first cards. if remaining_words != 0 cards[i] << pick_words[-remaining_words] remaining_words -= 1 end end # p cards # Output of the cards. If a word does not appear in a card, XXXX is output. for i in 0...(cards.length) print "Card #{i + 1}: " for j in 0...(phase.length) if cards[i].include? j print "#{phase[j]},\t" else print "XXXX,\t" end end puts end