| 1050 | #pragma GCC diagnostic ignored "-Wmissing-declarations" |
| 1051 | |
| 1052 | int mainEntryClickHouseObfuscator(int argc, char ** argv) |
| 1053 | try |
| 1054 | { |
| 1055 | using namespace DB; |
| 1056 | namespace po = boost::program_options; |
| 1057 | |
| 1058 | registerFormats(); |
| 1059 | |
| 1060 | po::options_description description = createOptionsDescription("Options", getTerminalWidth()); |
| 1061 | description.add_options() |
| 1062 | ("help", "produce help message") |
| 1063 | ("structure,S", po::value<std::string>(), "structure of the initial table (list of column and type names)") |
| 1064 | ("input-format", po::value<std::string>(), "input format of the initial table data") |
| 1065 | ("output-format", po::value<std::string>(), "default output format") |
| 1066 | ("seed", po::value<std::string>(), "seed (arbitrary string), must be random string with at least 10 bytes length; note that a seed for each column is derived from this seed and a column name: you can obfuscate data for different tables and as long as you use identical seed and identical column names, the data for corresponding non-text columns for different tables will be transformed in the same way, so the data for different tables can be JOINed after obfuscation") |
| 1067 | ("limit", po::value<UInt64>(), "if specified - stop after generating that number of rows") |
| 1068 | ("silent", po::value<bool>()->default_value(false), "don't print information messages to stderr") |
| 1069 | ("order", po::value<UInt64>()->default_value(5), "order of markov model to generate strings") |
| 1070 | ("frequency-cutoff", po::value<UInt64>()->default_value(5), "frequency cutoff for markov model: remove all buckets with count less than specified") |
| 1071 | ("num-buckets-cutoff", po::value<UInt64>()->default_value(0), "cutoff for number of different possible continuations for a context: remove all histograms with less than specified number of buckets") |
| 1072 | ("frequency-add", po::value<UInt64>()->default_value(0), "add a constant to every count to lower probability distribution skew") |
| 1073 | ("frequency-desaturate", po::value<double>()->default_value(0), "0..1 - move every frequency towards average to lower probability distribution skew") |
| 1074 | ("determinator-sliding-window-size", po::value<UInt64>()->default_value(8), "size of a sliding window in a source string - its hash is used as a seed for RNG in markov model") |
| 1075 | ; |
| 1076 | |
| 1077 | po::parsed_options parsed = po::command_line_parser(argc, argv).options(description).run(); |
| 1078 | po::variables_map options; |
| 1079 | po::store(parsed, options); |
| 1080 | |
| 1081 | if (options.count("help") |
| 1082 | || !options.count("seed") |
| 1083 | || !options.count("structure") |
| 1084 | || !options.count("input-format") |
| 1085 | || !options.count("output-format")) |
| 1086 | { |
| 1087 | std::cout << documentation << "\n" |
| 1088 | << "\nUsage: " << argv[0] << " [options] < in > out\n" |
| 1089 | << "\nInput must be seekable file (it will be read twice).\n" |
| 1090 | << "\n" << description << "\n" |
| 1091 | << "\nExample:\n " << argv[0] << " --seed \"$(head -c16 /dev/urandom | base64)\" --input-format TSV --output-format TSV --structure 'CounterID UInt32, URLDomain String, URL String, SearchPhrase String, Title String' < stats.tsv\n"; |
| 1092 | return 0; |
| 1093 | } |
| 1094 | |
| 1095 | UInt64 seed = sipHash64(options["seed"].as<std::string>()); |
| 1096 | |
| 1097 | std::string structure = options["structure"].as<std::string>(); |
| 1098 | std::string input_format = options["input-format"].as<std::string>(); |
| 1099 | std::string output_format = options["output-format"].as<std::string>(); |
| 1100 | |
| 1101 | UInt64 limit = 0; |
| 1102 | if (options.count("limit")) |
| 1103 | limit = options["limit"].as<UInt64>(); |
| 1104 | |
| 1105 | bool silent = options["silent"].as<bool>(); |
| 1106 | |
| 1107 | MarkovModelParameters markov_model_params; |
| 1108 | |
| 1109 | markov_model_params.order = options["order"].as<UInt64>(); |
no test coverage detected