Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] - Hash Generator #61

Merged
merged 13 commits into from
Oct 2, 2024
Merged
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();
});
});
24 changes: 24 additions & 0 deletions components/utils/hash-generator.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import crypto, { BinaryToTextEncoding } from "crypto";

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

try {
const hash = algorithm.startsWith("hmac")
? crypto.createHmac(algorithm.replace("hmac-", ""), secretKey!)
EduardoDePatta marked this conversation as resolved.
Show resolved Hide resolved
: 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 @@ -95,4 +95,10 @@ export const tools = [
"Test and debug your regular expressions in real-time. Provides quick feedback on pattern matching for strings.",
link: "/utilities/regex-tester",
},
{
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