• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2015, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <string>
16 #include <vector>
17 
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include <openssl/rand.h>
23 
24 #include "internal.h"
25 
26 
27 static const struct argument kArguments[] = {
28     {
29      "-hex", kBooleanArgument,
30      "Hex encoded output."
31     },
32     {
33      "", kOptionalArgument, "",
34     },
35 };
36 
Rand(const std::vector<std::string> & args)37 bool Rand(const std::vector<std::string> &args) {
38   bool forever = true, hex = false;
39   size_t len = 0;
40 
41   if (!args.empty()) {
42     std::vector<std::string> args_copy(args);
43     const std::string &last_arg = args.back();
44 
45     if (!last_arg.empty() && last_arg[0] != '-') {
46       char *endptr;
47       unsigned long long num = strtoull(last_arg.c_str(), &endptr, 10);
48       if (*endptr == 0) {
49         len = num;
50         forever = false;
51         args_copy.pop_back();
52       }
53     }
54 
55     std::map<std::string, std::string> args_map;
56     if (!ParseKeyValueArguments(&args_map, args_copy, kArguments)) {
57       PrintUsage(kArguments);
58       return false;
59     }
60 
61     hex = args_map.count("-hex") > 0;
62   }
63 
64   uint8_t buf[4096];
65   uint8_t hex_buf[8192];
66 
67   size_t done = 0;
68   while (forever || done < len) {
69     size_t todo = sizeof(buf);
70     if (!forever && todo > len - done) {
71       todo = len - done;
72     }
73     RAND_bytes(buf, todo);
74     if (hex) {
75       static const char hextable[16 + 1] = "0123456789abcdef";
76       for (unsigned i = 0; i < todo; i++) {
77         hex_buf[i*2] = hextable[buf[i] >> 4];
78         hex_buf[i*2 + 1] = hextable[buf[i] & 0xf];
79       }
80       if (fwrite(hex_buf, todo*2, 1, stdout) != 1) {
81         return false;
82       }
83     } else {
84       if (fwrite(buf, todo, 1, stdout) != 1) {
85         return false;
86       }
87     }
88     done += todo;
89   }
90 
91   if (hex && fwrite("\n", 1, 1, stdout) != 1) {
92     return false;
93   }
94 
95   return true;
96 }
97