You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

96 lines
2.5 KiB

  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. #include <string>
  15. #include <vector>
  16. #include <stdint.h>
  17. #include <stdlib.h>
  18. #include <openssl/rand.h>
  19. #include "internal.h"
  20. static const struct argument kArguments[] = {
  21. {
  22. "-hex", kBooleanArgument,
  23. "Hex encoded output."
  24. },
  25. {
  26. "", kOptionalArgument, "",
  27. },
  28. };
  29. bool Rand(const std::vector<std::string> &args) {
  30. bool forever = true, hex = false;
  31. size_t len = 0;
  32. if (!args.empty()) {
  33. std::vector<std::string> args_copy(args);
  34. const std::string &last_arg = args.back();
  35. if (last_arg.size() > 0 && last_arg[0] != '-') {
  36. char *endptr;
  37. unsigned long long num = strtoull(last_arg.c_str(), &endptr, 10);
  38. if (*endptr == 0) {
  39. len = num;
  40. forever = false;
  41. args_copy.pop_back();
  42. }
  43. }
  44. std::map<std::string, std::string> args_map;
  45. if (!ParseKeyValueArguments(&args_map, args_copy, kArguments)) {
  46. PrintUsage(kArguments);
  47. return false;
  48. }
  49. hex = args_map.count("-hex") > 0;
  50. }
  51. uint8_t buf[4096];
  52. uint8_t hex_buf[8192];
  53. size_t done = 0;
  54. while (forever || done < len) {
  55. size_t todo = sizeof(buf);
  56. if (!forever && todo > len - done) {
  57. todo = len - done;
  58. }
  59. RAND_bytes(buf, todo);
  60. if (hex) {
  61. static const char hextable[16 + 1] = "0123456789abcdef";
  62. for (unsigned i = 0; i < todo; i++) {
  63. hex_buf[i*2] = hextable[buf[i] >> 4];
  64. hex_buf[i*2 + 1] = hextable[buf[i] & 0xf];
  65. }
  66. if (fwrite(hex_buf, todo*2, 1, stdout) != 1) {
  67. return false;
  68. }
  69. } else {
  70. if (fwrite(buf, todo, 1, stdout) != 1) {
  71. return false;
  72. }
  73. }
  74. done += todo;
  75. }
  76. if (hex && fwrite("\n", 1, 1, stdout) != 1) {
  77. return false;
  78. }
  79. return true;
  80. }