summaryrefslogtreecommitdiff
path: root/src/main.c
blob: 6e28a853aabb7c63da382a9156201efce599abdf (plain)
    1 // upwgen generates random internationalized passwords
    2 // Copyright (C) 2019  Aaron Ball <nullspoon@oper.io>
    3 // 
    4 // This program is free software: you can redistribute it and/or modify
    5 // it under the terms of the GNU General Public License as published by
    6 // the Free Software Foundation, either version 3 of the License, or
    7 // (at your option) any later version.
    8 // 
    9 // This program is distributed in the hope that it will be useful,
   10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12 // GNU General Public License for more details.
   13 // 
   14 // You should have received a copy of the GNU General Public License
   15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
   16 #include <stdlib.h>
   17 #include <stdio.h>
   18 #include <time.h>
   19 #include <locale.h>
   20 
   21 
   22 // intrcat:
   23 // Integer range concatenate. Appends the specified integer range to an int
   24 // array.
   25 //
   26 // @arr    Array to cat range of ints to
   27 // @rstart Range start integer
   28 // @rend   Range end integer
   29 //
   30 // @return Number of integers appended to array
   31 int intrcat(unsigned int* arr, unsigned int rstart, unsigned int rend) {
   32   int i = 0;
   33   int total = rend - rstart; // Calculate our return count
   34 
   35   while(arr[i] != '\0')
   36     i++;
   37 
   38   while(rstart <= rend) {
   39     arr[i] = rstart;
   40     //printf("% -4d % -7d   %lc\n", i, rstart, rstart);
   41     rstart++;
   42     i++;
   43   }
   44 
   45   arr[i] = '\0';
   46   return total;
   47 }
   48 
   49 
   50 // populate_intl_arr:
   51 // Populates an unsigned integer array with common unicode (utf-8) language
   52 // alphabets and symbols.
   53 //
   54 // Some example unicode integer ranges:
   55 //   33 - 126      Standard english ascii
   56 //   256 - 383     Latin extended A block
   57 //   256 - 383     Latin extended B block
   58 //   913 - 969     Greek
   59 //   1040 - 1103   Russian
   60 //   1329 - 1414   Armenian
   61 //   1488 - 1514   Hebrew
   62 //   65166 - 65265 Arabic
   63 // 
   64 //   No/rare font support (boo!)
   65 //   2325 - 2373   Devanagari (Hindi)
   66 //   2437 - 2509   Bengali alphabet
   67 //   2949 - 3020   Tamil
   68 //   3585 - 3663   Thai
   69 //   5792 - 5880   Runic
   70 //   11392 - 11483 Coptic alphabet
   71 //   66560 - 66639 Deseret
   72 //
   73 // @out  Unsigned int array to be populated.
   74 //
   75 // @return Size of the array contents
   76 int populate_intl_arr(unsigned int* out) {
   77   out[0] = '\0';
   78   int count = 0;
   79 
   80   // Populate the array
   81   count += intrcat(out, 33, 126);      // English
   82   count += intrcat(out, 256, 383);     // Latin A block
   83   count += intrcat(out, 399, 691);     // Latin B block
   84   count += intrcat(out, 913, 969);     // Greek
   85   count += intrcat(out, 1040, 1103);   // Russian
   86   count += intrcat(out, 1329, 1414);   // Armenian
   87   count += intrcat(out, 1488, 1514);   // Hebrew
   88   count += intrcat(out, 65166, 65265); // Arabic
   89 
   90   return count;
   91 }
   92 
   93 
   94 // print_intl_arr:
   95 // Prints array containing unsigned ints representing internal characters.
   96 // Outputs to STDOUT the unicode decimal, followed by the unicode character.
   97 //
   98 // @arr Unicode array to print
   99 void print_intl_arr(unsigned int* arr) {
  100   int i = 0; // cursor
  101 
  102   while(arr[i] != '\0') {
  103     printf("%5d: [%lc]\n", arr[i], arr[i]);
  104     i++;
  105   }
  106 }
  107 
  108 
  109 int main(int argc, char* argv[]) {
  110   char* passlen;      // Argv 1, user specified length of the password
  111   int count;          // Number of international chars to choose from
  112   struct timespec ts; // Timespec for seeding rng
  113   int len;            // Password length
  114   unsigned long seed; // Seed for the RNG (current seconds * nanoseconds)
  115   unsigned int chars[1024]; // Uint array to hold international chars
  116 
  117   setlocale(LC_ALL, "en_US.UTF-8");
  118 
  119   if(argc == 1) {
  120     printf("Password length required\n");
  121     return 1;
  122   }
  123 
  124   passlen = argv[1];
  125 
  126   // Store supported chars here!
  127   count = populate_intl_arr(chars);
  128   //printf("%d international chars for use\n", count);
  129   //print_intl_arr(chars);
  130   //return 0;
  131 
  132   clock_gettime(CLOCK_REALTIME, &ts);
  133   seed = ts.tv_sec + ts.tv_nsec;
  134   srand((unsigned)seed);
  135 
  136   len = atoi(passlen);
  137   while(len > 0) {
  138     int r = rand() % count;
  139     printf("%lc", chars[r]);
  140     len--;
  141   }
  142   printf("\n");
  143 
  144   return 0;
  145 }

Generated by cgit