Skip to content

Instantly share code, notes, and snippets.

@shaman007
Created July 30, 2025 12:59
Show Gist options
  • Save shaman007/48d713a8ca983891b3445c06a3cf126e to your computer and use it in GitHub Desktop.
Save shaman007/48d713a8ca983891b3445c06a3cf126e to your computer and use it in GitHub Desktop.
Fake leaks generator
# gem 'faker', '~> 3.4'
require 'faker'
require 'i18n'
require 'json'
require 'csv'
Faker::Config.locale = 'ru'
I18n.backend.store_translations('ru', {
faker: {
rural18c: {
male_first_name: %w[Аввакум Авдей Артемий Афанасий Василий Гаврила Герасим Григорий Демид
Емельян Елисей Ерофей Захар Игнат Иван Кондрат Кузьма Макар Мирон Никита
Павел Прокопий Савва Семён Степан Тихон Федор Фрол Яков],
female_first_name: %w[Агафья Аксинья Анфиса Авдотья Дарья Евдокия Евфросиния Ефимья Марфа
Матрёна Пелагея Прасковья Фёкла Харитина],
father_name: %w[Алексей Андрей Афанасий Василий Герасим Григорий Демид Емельян Захар Игнат
Иван Кондрат Кузьма Макар Мирон Никита Павел Прокопий Савва Семён Степан Тихон
Фёдор Фрол Яков],
surnames: %w[Смирнов Иванов Петров Сидоров Кузнецов Попов Васильев Новиков Фёдоров Морозов
Волков Алексеев Лебедев Семёнов Егоров Павлов Козлов Степанов Николаев Орлов
Макаров Захаров Андреев Богданов Титов Крылов Романов Королёв Сергеев Филиппов],
companies: [
"Газпром","Роснефть","Росатом","РЖД","Сбер","ВТБ","Ростелеком","Аэрофлот","Транснефть",
"РусГидро","АЛРОСА","Роскосмос","Объединённая авиастроительная корпорация",
"Объединённая судостроительная корпорация","Россети","Росгеология","Роснано"
],
titles: [
"Вице-президент по инновациям",
"Заместитель генерального директора по стратегическому развитию",
"Исполнительный директор по цифровой трансформации",
"Директор департамента корпоративного управления",
"Начальник управления проектного офиса",
"Советник председателя правления",
"Руководитель службы взаимодействия с органами власти",
"Директор по устойчивому развитию",
"Директор по безопасности",
"Директор по GR",
"Главный аналитик по импортозамещению",
"Начальник управления капитального строительства"
]
}
}
})
module Faker
class Rural18c < Base
class << self
def male_first_name = sample(t('male_first_name'))
def female_first_name = sample(t('female_first_name'))
def father_name = sample(t('father_name'))
def surname = sample(t('surnames'))
def company = sample(t('companies'))
def title = sample(t('titles'))
def patronymic_male(from = father_name) = morph_patronymic(from, :m)
def patronymic_female(from = father_name) = morph_patronymic(from, :f)
def full_name_male
"#{male_first_name} #{patronymic_male} #{surname_for(:m)}"
end
def full_name_female
"#{female_first_name} #{patronymic_female} #{surname_for(:f)}"
end
def persona(sex: [:m, :f].sample)
name = (sex == :m) ? full_name_male : full_name_female
{
name: name,
origin: company, # крупная госкомпания РФ
title: title # пафосная должность
}
end
# --- helpers ---
def t(key) = translate("faker.rural18c.#{key}")
def morph_patronymic(base, gender)
stem = base.dup
# очень упрощённые правила
case stem
when /ий\z/ then stem = stem.sub(/ий\z/, 'ь')
when /ей\z/ then stem = stem.sub(/ей\z/, 'е')
when /а\z/ then stem = stem.sub(/а\z/, '')
when /й\z/ then stem = stem.sub(/й\z/, 'е')
end
gender == :m ? "#{stem}ович" : "#{stem}овна"
end
def surname_for(g)
s = surname
# родовые окончания для простых фамилий типа Иванов/Петров -> Иванова/Петрова
if g == :f && s =~ /(ов|ев|ин|ын)\z/
s + "а"
else
s
end
end
end
end
end
# --- генерация и сохранение ---
count = (ENV['N'] || 50).to_i
rows = Array.new(count) do
sex = [:m, :f].sample
Faker::Rural18c.persona(sex: sex)
end
# JSON
File.write('personas.json', JSON.pretty_generate(rows))
# CSV
CSV.open('personas.csv', 'w', col_sep: ';') do |csv|
csv << %w[name origin title]
rows.each { |r| csv << [r[:name], r[:origin], r[:title]] }
end
puts "Generated #{rows.size} personas -> personas.json, personas.csv"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment