Skip to content

Commit

Permalink
Merge pull request #61 from EduardoDePatta/feature/hash-generator
Browse files Browse the repository at this point in the history
[Feat] - Hash Generator
  • Loading branch information
peckz authored Oct 2, 2024
2 parents d205fb4 + f5c2755 commit 2439547
Show file tree
Hide file tree
Showing 6 changed files with 476 additions and 1 deletion.
2 changes: 1 addition & 1 deletion components/ds/InputComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
"flex h-10 w-full rounded-lg border border-input bg-muted px-3 py-2 font-light ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-base",
"flex h-10 w-full rounded-lg border border-input bg-muted px-3 py-2 ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-sm",
className
)}
ref={ref}
Expand Down
77 changes: 77 additions & 0 deletions components/seo/HashGeneratorSEO.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
export default function HashGeneratorSEO() {
return (
<div className="content-wrapper">
<section>
<h2>Generate Secure Hashes Online</h2>
<p>
Jam's Hash Generator tool allows you to generate secure hashes using
various algorithms like SHA-256, SHA-512, MD5, and PBKDF2. Whether
you're working on web development, data integrity, or cryptographic
applications, our hash generator provides a simple and efficient way
to create hashes.
</p>
</section>

<section>
<h2>How to Use the Hash Generator</h2>
<ul>
<li>
<b>Input your text:</b> <br /> Enter the text you want to hash in
the provided field.
</li>
<li>
<b>Select the algorithm:</b> <br /> Choose from SHA-256, SHA-512,
MD5, PBKDF2, or HMAC.
</li>
<li>
<b>Optional parameters:</b> <br /> Depending on the algorithm, you
can provide a salt, a secret key, or adjust the number of iterations
and output length.
</li>
<li>
<b>Generate the hash:</b> <br /> Click "Generate Hash" to get the
resulting hash. You can then copy it to your clipboard.
</li>
</ul>
</section>

<section>
<h2>Benefits of Using Hash Functions</h2>
<ul>
<li>
<b>Data Integrity:</b> <br /> Ensure the integrity of your data by
generating and verifying hashes.
</li>
<li>
<b>Security:</b> <br /> Hash functions like SHA-256 and SHA-512 are
widely used in cryptographic applications to protect data.
</li>
<li>
<b>Consistency:</b> <br /> Hashing provides a consistent output for
the same input, making it ideal for checksums and data validation.
</li>
</ul>
</section>

<section>
<h2>Understanding Hashing Algorithms</h2>
<p>
Hash functions are mathematical algorithms that take an input (or
'message') and return a fixed-size string of bytes. The output,
typically referred to as a hash code, is unique to the provided input.
</p>
<p>
Algorithms like SHA-256 and SHA-512 are part of the SHA-2 family,
providing strong security for various applications. PBKDF2 is used to
derive a cryptographic key from a password, providing an extra layer
of security through multiple iterations.
</p>
<p>
HMAC (Hash-based Message Authentication Code) is another variant that
uses a secret key to provide additional security, commonly used in
secure communication protocols.
</p>
</section>
</div>
);
}
82 changes: 82 additions & 0 deletions components/utils/hash-generator.utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { generateHash } from "./hash-generator.utils";
import crypto from "crypto";

describe("generateHash", () => {
it("should generate a valid SHA-256 hash", () => {
const hash = generateHash("sha256", "test");
expect(hash).toBe(
"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
);
});

it("should generate a valid SHA-512 hash", () => {
const hash = generateHash("sha512", "test");
expect(hash).toBe(
"ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"
);
});

it("should generate a valid MD5 hash", () => {
const hash = generateHash("md5", "test");
expect(hash).toBe("098f6bcd4621d373cade4e832627b4f6");
});

it("should generate a SHA-256 hash with base64 encoding", () => {
const hash = generateHash("sha256", "test", "base64");
expect(hash).toBe("n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=");
});

it("should generate a valid HMAC-SHA-256 hash", () => {
const secretKey = "mySecretKey";
const hash = generateHash("hmac-sha256", "test", "hex", secretKey);

const expectedHash = crypto
.createHmac("sha256", secretKey)
.update("test")
.digest("hex");
expect(hash).toBe(expectedHash);
});

it("should generate a valid HMAC-SHA-512 hash", () => {
const secretKey = "mySecretKey";
const hash = generateHash("hmac-sha512", "test", "hex", secretKey);

const expectedHash = crypto
.createHmac("sha512", secretKey)
.update("test")
.digest("hex");
expect(hash).toBe(expectedHash);
});

it("should throw an error if data is an empty string", () => {
expect(() => generateHash("sha256", "")).toThrow(
"Data must be a non-empty string"
);
});

it("should throw an error if data is not a string", () => {
expect(() => generateHash("sha256", 123 as unknown as string)).toThrow(
"Data must be a non-empty string"
);
});

it("should throw an error for unsupported algorithm", () => {
expect(() => generateHash("unsupportedAlgo", "test")).toThrow(
"Failed to generate hash:"
);
});

it("should throw an unknown error if a non-error is thrown", () => {
const mockCrypto = jest
.spyOn(crypto, "createHash")
.mockImplementation(() => {
throw "unexpected error";
});

expect(() => generateHash("sha256", "test")).toThrow(
"Failed to generate hash: An unknown error occurred"
);

mockCrypto.mockRestore();
});
});
38 changes: 38 additions & 0 deletions components/utils/hash-generator.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import crypto, { BinaryToTextEncoding } from "crypto";

export type Algorithm =
| "sha256"
| "sha512"
| "md5"
| "pbkdf2"
| "hmac-sha256"
| "hmac-sha512";

export const generateHash = (
algorithm: Algorithm,
data: string,
encoding: BinaryToTextEncoding = "hex",
secretKey?: string
): string => {
if (typeof data !== "string" || data.trim() === "") {
throw new Error("Data must be a non-empty string");
}

if (algorithm.startsWith("hmac") && !secretKey) {
throw new Error("Secret key must be provided for HMAC algorighms");
}

const secret = secretKey || crypto.randomBytes(32).toString("hex");

try {
const hash = algorithm.startsWith("hmac")
? crypto.createHmac(algorithm.replace("hmac-", ""), secret)
: crypto.createHash(algorithm);

return hash.update(data).digest(encoding);
} catch (error) {
throw new Error(
`Failed to generate hash: ${error instanceof Error ? error.message : "An unknown error occurred"}`
);
}
};
6 changes: 6 additions & 0 deletions components/utils/tools-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,10 @@ export const tools = [
"Easily decode JWT tokens and view their header, payload, and signature. Perfect for debugging and analyzing JSON Web Tokens.",
link: "/utilities/jwt-parser",
},
{
title: "Hash Generator",
description:
"Quickly generate secure hashes for your text using algorithms like SHA-256, SHA-512, MD5, and more. Ideal for password hashing, data integrity checks, and cryptographic applications.",
link: "/utilities/hash-generator",
},
];
Loading

0 comments on commit 2439547

Please sign in to comment.