Here's a first version, written in D, and following Script Coder's suggestion.
Unfortunately the D library developers have yet to implement SHA-2 so I had to use SHA-1.
What else can I say? It seems to be working. Let me know if you spot something wrong.
And if you actually want to use this utility, I suggest generating a custom Mode (containing no more than 256 characters for obvious reasons) and to always chain the program at least twice, as in:
import std.array;
import std.conv;
import std.digest.sha;
import std.stdio;
alias SHA1 HashFunction;
version = Mode1;
void main(string[] args)
{
version (Mode0)
{
immutable string mode =
"abcdefghijklmnopqrstuvwxyz""ABCDEFGHIJKLMNOPQRSTUVWXYZ""0123456789";
}
version (Mode1)
{
immutable string mode =
"abcdefghijklmnopqrstuvwxyz""ABCDEFGHIJKLMNOPQRSTUVWXYZ""0123456789""_";
}
version (Mode2)
{
immutable string mode =
"abcdefghijklmnopqrstuvwxyz""ABCDEFGHIJKLMNOPQRSTUVWXYZ""0123456789""~`!@#$%^&*()_-+=|\\{[}]:;\"'<,>.?/";
}
/*
Here you can add custom modes, with the obvious caveat
that if you lose your program, you will no longer be
able to regenerate your passwords.
*/
/+
version (CustomMode)
{
immutable string mode = "";
}
+/
void printUsage(string errorMessage = "")
{
stderr.writeln("\nPassReGen usage:");
stderr.writeln("\n\t", args[0], " length [filename]\n");
stderr.writeln("Where:\n\t`length' is an unsigned integer, representing");
stderr.writeln("\tthe generated password's length in characters, and\n");
stderr.writeln("\t`filename' is an optional parameter representing the input file.");
stderr.writeln("\tIf it is missing, the program reads a line from Standard Input.\n");
stderr.writeln("Usage examples:");
stderr.writeln('\t', args[0], " 20 readme.txt");
stderr.writeln("\techo MyPassword| ", args[0], " 20\n");
if (!errorMessage.empty)
stderr.writeln(errorMessage);
stderr.writeln();
}
ubyte[digestLength!HashFunction] indices;
if (args.length == 2)
{
indices = digest!HashFunction(readln());
}
elseif (args.length == 3)
{
indices = digest!HashFunction(File(args[2]).byChunk(4096));
}
else
{
printUsage();
return;
}
char[] password;
password.length = parse!size_t(args[1]);
foreach (i, ref c; password)
{
if (i != 0 && i % indices.length == 0)
indices = digest!HashFunction(indices);
c = mode[indices[i % indices.length] % mode.length];
}
writeln(password);
}
@Catfish666 That looks quite cool. I do not have a D compiler, but I might convert it to c++ if I find the time. Also, if you really wanted to you could self implement a SHA-2 library in D. I am sure the D community would be grateful.
It's inspired by it quite a bit. That and Java syntax. And you'll find hints of various other languages here and there.
True most of the code is readable, but would someone mind explaining the following pieces of syntax do: version
/+ +/
Guessing this is a type of comment. digestLength!HashFunction
This looks like a type of member reference, similar to C++'s ->
i remember in an earlier post that ! is for templates. i could be wrong though
http://dlang.org/template.html
http://dlang.org/ddoc.html for the /+ +/
idk what version is
@ Script Coder: to be honest I don't like how you mix std::string and C-style byte arrays. You even included vector and then never used it.
Those C-style casts hint that there's room for improvement.
Also from what I see your program can't be piped, quitting immediately if there aren't exactly three arguments. Then again, perhaps piping doesn't really help that much.
Finally, I'm curious why you chose SHA-256 instead of SHA-384 or SHA-512.
to be honest I don't like how you mix std::string and C-style byte arrays
I do not like it either, but I either have to use solely C-style byte arrays, or I have to mix them. I cannot think of another alternative.
Catfish666 wrote:
You even included vector and then never used it.
Allow me to explain. I compete in many programming competitions and the first four include's are automatically placed there for speed.
Catfish666 wrote:
Also from what I see your program can't be piped
I do not know how to pipe, but I'll look it up, if it is really necessary. Which as far as I understand just confuses your end user, especially if they are not tech savy.
Catfish666 wrote:
Finally, I'm curious why you chose SHA-256 instead of SHA-384 or SHA-512.
256/8=32. Where are you ever allowed to enter a password longer than this? Is that amount of security needed?
It is easily fixable, one could even allow for multiple options if one develops the program further.
Please give more detail, I do not understand this concept fully, and thus do not understand how it solves anything.
DTSCode wrote:
what competitions are these? ive been looking to get into a few
These are the ones I compete and practice on regularly:
USACO - 13 December is the next one. Has a training site, probably the best.
COCI - 7 December is the next one
CodeForces - continuously has competitions. Has timed past papers.
You can also practice on past papers with all of these. Also, the above are only algorithmic contests. Good luck.