mirror of
https://github.com/ershisan99/DevToysWeb.git
synced 2025-12-17 04:59:23 +00:00
feat: add hash generator
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
"@mui/icons-material": "^5.5.1",
|
"@mui/icons-material": "^5.5.1",
|
||||||
"@mui/material": "^5.5.1",
|
"@mui/material": "^5.5.1",
|
||||||
"ace-builds": "^1.4.14",
|
"ace-builds": "^1.4.14",
|
||||||
|
"create-hash": "^1.2.0",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"fp-ts": "^2.11.9",
|
"fp-ts": "^2.11.9",
|
||||||
"fuse.js": "^6.5.3",
|
"fuse.js": "^6.5.3",
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@emotion/babel-plugin": "^11.7.2",
|
"@emotion/babel-plugin": "^11.7.2",
|
||||||
|
"@types/create-hash": "^1.2.2",
|
||||||
"@types/node": "^16.11.45",
|
"@types/node": "^16.11.45",
|
||||||
"@types/react": "17.0.41",
|
"@types/react": "17.0.41",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.15.0",
|
"@typescript-eslint/eslint-plugin": "^5.15.0",
|
||||||
|
|||||||
36
src/components/pages/generators/hash/Configuration.tsx
Normal file
36
src/components/pages/generators/hash/Configuration.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { FontDownload } from "@mui/icons-material";
|
||||||
|
import { FormControlLabel, Switch } from "@mui/material";
|
||||||
|
import { SwitchBaseProps } from "@mui/material/internal/SwitchBase";
|
||||||
|
import { memo } from "react";
|
||||||
|
|
||||||
|
import { Configurations } from "@/components/common";
|
||||||
|
|
||||||
|
type SwitchChecked = NonNullable<SwitchBaseProps["checked"]>;
|
||||||
|
type OnSwitchChange = NonNullable<SwitchBaseProps["onChange"]>;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
uppercase: SwitchChecked;
|
||||||
|
onCaseChange: OnSwitchChange;
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledComponent = ({ uppercase, onCaseChange }: Props) => (
|
||||||
|
<Configurations
|
||||||
|
configurations={[
|
||||||
|
{
|
||||||
|
icon: <FontDownload />,
|
||||||
|
title: "Uppercase",
|
||||||
|
input: (
|
||||||
|
<FormControlLabel
|
||||||
|
labelPlacement="start"
|
||||||
|
label={uppercase ? "On" : "Off"}
|
||||||
|
control={<Switch checked={uppercase} onChange={onCaseChange} />}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
95
src/components/pages/generators/hash/Content.tsx
Normal file
95
src/components/pages/generators/hash/Content.tsx
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import { Stack } from "@mui/material";
|
||||||
|
import createHash from "create-hash"; // smaller bundle size than Node.js standard library
|
||||||
|
import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react";
|
||||||
|
|
||||||
|
import { Main, MainItem, TextField } from "@/components/common";
|
||||||
|
|
||||||
|
import Configuration from "./Configuration";
|
||||||
|
|
||||||
|
type TextFieldValue = ComponentPropsWithoutRef<typeof TextField>["value"];
|
||||||
|
type OnTextFieldChange = NonNullable<ComponentPropsWithoutRef<typeof TextField>["onChange"]>;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
input: TextFieldValue;
|
||||||
|
md5: TextFieldValue;
|
||||||
|
sha1: TextFieldValue;
|
||||||
|
sha256: TextFieldValue;
|
||||||
|
sha512: TextFieldValue;
|
||||||
|
onInputChange: OnTextFieldChange;
|
||||||
|
} & ComponentPropsWithoutRef<typeof Configuration>;
|
||||||
|
|
||||||
|
const StyledComponent = ({
|
||||||
|
uppercase,
|
||||||
|
input,
|
||||||
|
md5,
|
||||||
|
sha1,
|
||||||
|
sha256,
|
||||||
|
sha512,
|
||||||
|
onCaseChange,
|
||||||
|
onInputChange,
|
||||||
|
}: Props) => (
|
||||||
|
<Main title="Hash Generator">
|
||||||
|
<MainItem title="Configuration">
|
||||||
|
<Configuration {...{ uppercase, onCaseChange }} />
|
||||||
|
</MainItem>
|
||||||
|
<MainItem title="Input">
|
||||||
|
<TextField multiline rows={5} value={input} onChange={onInputChange} />
|
||||||
|
</MainItem>
|
||||||
|
<Stack spacing={1}>
|
||||||
|
<MainItem title="MD5">
|
||||||
|
<TextField value={md5} InputProps={{ readOnly: true }} />
|
||||||
|
</MainItem>
|
||||||
|
<MainItem title="SHA1">
|
||||||
|
<TextField value={sha1} InputProps={{ readOnly: true }} />
|
||||||
|
</MainItem>
|
||||||
|
<MainItem title="SHA256">
|
||||||
|
<TextField value={sha256} InputProps={{ readOnly: true }} />
|
||||||
|
</MainItem>
|
||||||
|
<MainItem title="SHA512">
|
||||||
|
<TextField value={sha512} InputProps={{ readOnly: true }} />
|
||||||
|
</MainItem>
|
||||||
|
</Stack>
|
||||||
|
</Main>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
const Container = () => {
|
||||||
|
const [uppercase, setUppercase] = useState(false);
|
||||||
|
const [input, setInput] = useState("Hello there !");
|
||||||
|
|
||||||
|
const onCaseChange: Props["onCaseChange"] = useCallback((_e, checked) => {
|
||||||
|
setUppercase(checked);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onInputChange: Props["onInputChange"] = useCallback(({ currentTarget: { value } }) => {
|
||||||
|
setInput(value);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const newMd5 = createHash("md5").update(input).digest("hex");
|
||||||
|
const newSha1 = createHash("sha1").update(input).digest("hex");
|
||||||
|
const newSha256 = createHash("sha256").update(input).digest("hex");
|
||||||
|
const newSha512 = createHash("sha512").update(input).digest("hex");
|
||||||
|
|
||||||
|
const md5 = uppercase ? newMd5.toUpperCase() : newMd5;
|
||||||
|
const sha1 = uppercase ? newSha1.toUpperCase() : newSha1;
|
||||||
|
const sha256 = uppercase ? newSha256.toUpperCase() : newSha256;
|
||||||
|
const sha512 = uppercase ? newSha512.toUpperCase() : newSha512;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
{...{
|
||||||
|
uppercase,
|
||||||
|
input,
|
||||||
|
md5,
|
||||||
|
sha1,
|
||||||
|
sha256,
|
||||||
|
sha512,
|
||||||
|
onCaseChange,
|
||||||
|
onInputChange,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Container;
|
||||||
3
src/components/pages/generators/hash/index.ts
Normal file
3
src/components/pages/generators/hash/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Content from "./Content";
|
||||||
|
|
||||||
|
export { Content };
|
||||||
@@ -112,8 +112,8 @@ const toolGroups = [
|
|||||||
longTitle: "Hash Generator",
|
longTitle: "Hash Generator",
|
||||||
description: "Calculate MD5, SHA1, SHA256 and SHA512 hash from text data",
|
description: "Calculate MD5, SHA1, SHA256 and SHA512 hash from text data",
|
||||||
keywords: "hash generator md5 sha1 sha256 sha512",
|
keywords: "hash generator md5 sha1 sha256 sha512",
|
||||||
href: pagesPath.$url(),
|
href: pagesPath.generators.hash.$url(),
|
||||||
disabled: true,
|
disabled: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <Numbers />,
|
icon: <Numbers />,
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ export const pagesPath = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
generators: {
|
||||||
|
hash: {
|
||||||
|
$url: (url?: { hash?: string }) => ({
|
||||||
|
pathname: "/generators/hash" as const,
|
||||||
|
hash: url?.hash,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
search: {
|
search: {
|
||||||
$url: (url?: { hash?: string }) => ({ pathname: "/search" as const, hash: url?.hash }),
|
$url: (url?: { hash?: string }) => ({ pathname: "/search" as const, hash: url?.hash }),
|
||||||
},
|
},
|
||||||
|
|||||||
7
src/pages/generators/hash.tsx
Normal file
7
src/pages/generators/hash.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import type { NextPage } from "next";
|
||||||
|
|
||||||
|
import { Content } from "@/components/pages/generators/hash";
|
||||||
|
|
||||||
|
const Page: NextPage = Content;
|
||||||
|
|
||||||
|
export default Page;
|
||||||
Reference in New Issue
Block a user