Skip to content

Commit

Permalink
feat(hashFile): 新增文件hash工具
Browse files Browse the repository at this point in the history
  • Loading branch information
ZvonimirSun committed Dec 27, 2023
1 parent f863f67 commit 5088075
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ declare module 'vue' {
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer']
Expand Down
4 changes: 4 additions & 0 deletions src/tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
"name": "文本HASH",
"link": "/hashText"
},
{
"name": "文件HASH",
"link": "/hashFile"
},
{
"name": "在线JWT解密",
"link": "/jwt"
Expand Down
13 changes: 13 additions & 0 deletions src/views/hashFile/hashFile.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MD5, SHA1, SHA256, SHA3, SHA512 } from 'crypto-js'

export const algos = {
MD5,
SHA1,
SHA256,
SHA512,
SHA3
} as const

export type AlgoNames = keyof typeof algos;

export const algoNames = Object.keys(algos) as AlgoNames[]
153 changes: 153 additions & 0 deletions src/views/hashFile/hashFile.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<script setup lang="ts">
import HashFileWorker from './hashFile.worker?worker'
import type { AlgoNames } from './hashFile.service'
import formatBytes from '@/utils/formatBytes'
const { post, data, terminate } = useWebWorker<{
[K in AlgoNames]: string
} | undefined>(new HashFileWorker())
const { copy } = useCopy({ text: '复制成功' })
let tmpFile: File | undefined
const algoNames = ref<AlgoNames[]>([])
const algos = ref<AlgoNames[]>(['MD5'])
const fileInfo = ref('')
const loading = computed(() => {
if (!fileInfo.value) {
return false
} else if (!data.value) {
return true
} else {
return Object.keys(data.value).length !== algos.value.length
}
})
onBeforeMount(async () => {
algoNames.value = (await import('./hashFile.service')).algoNames
})
onUnmounted(() => {
terminate()
})
function updateAlgos () {
tmpFile = undefined
data.value = undefined
fileInfo.value = ''
if (algos.value.length === 0) {
algos.value = ['MD5']
}
}
function calculate (rawFile: File) {
tmpFile = rawFile
fileInfo.value = `${rawFile.name} (类型: ${rawFile.type}, 大小: ${formatBytes(rawFile.size)})`
post({ value: tmpFile, algos: toRaw(algos.value) })
return false
}
</script>

<template>
<div
w-full
h-full
overflow-auto
flex
flex-col
items-center
>
<div
w-250
max-w-full
flex
flex-col
gap-4
>
<el-alert
title="文件不会被上传"
type="info"
show-icon
center
/>
<el-upload
class="upload-demo"
drag
multiple
:before-upload="calculate"
:disabled="loading"
:show-file-list="false"
>
<i class="i-icon-park-outline-upload-one el-icon--upload" />
<div class="el-upload__text">
将文件拖拽到此处 或 <em>点击选择文件</em>
</div>
</el-upload>
<el-checkbox-group
v-if="algoNames"
v-model="algos"
:disabled="loading"
@change="updateAlgos"
>
<el-checkbox
v-for="algo in algoNames"
:key="algo"
:label="algo"
/>
</el-checkbox-group>
<div
v-if="fileInfo"
>
<el-input
v-model="fileInfo"
readonly
>
<template #prepend>
<span
w-32
select-none
>文件名称</span>
</template>
<template #append>
<el-button @click="copy(fileInfo)">
<i class="i-icon-park-outline-copy" />
</el-button>
</template>
</el-input>
</div>
<template v-if="algos && fileInfo">
<el-divider
mt-4
mb-4
/>
<div
v-loading="loading"
flex
flex-col
gap-4
>
<el-input
v-for="algo in algos"
:key="algo"
:model-value="data?.[algo]"
readonly
>
<template #prepend>
<span
w-32
select-none
>{{ algo }}</span>
</template>
<template
v-if="data?.[algo]"
#append
>
<el-button @click="copy(data[algo])">
<i class="i-icon-park-outline-copy" />
</el-button>
</template>
</el-input>
</div>
</template>
</div>
</div>
</template>
22 changes: 22 additions & 0 deletions src/views/hashFile/hashFile.worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { lib } from 'crypto-js'
import { algos, type AlgoNames } from './hashFile.service'

const hashFile = (algo: AlgoNames, value: lib.WordArray) => algos[algo](value).toString()

self.addEventListener('message', function (event) {
if (event.data && event.data.value && event.data.value instanceof File) {
const algos = (event.data.algos || ['MD5']) as AlgoNames[]
const reader = new FileReader()
reader.readAsArrayBuffer(event.data.value)
reader.onload = function () {
const wordArray = lib.WordArray.create(reader.result as unknown as number[])
const result = {} as { [key in AlgoNames]: string }
for (const algo of algos) {
result[algo] = hashFile(algo, wordArray)
self.postMessage(result)
}
}
} else {
self.postMessage(null)
}
})
4 changes: 0 additions & 4 deletions src/views/hashText/hashText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,3 @@ function calculate () {
</div>
</div>
</template>

<style scoped lang="scss">
</style>
1 change: 0 additions & 1 deletion src/views/idChinese/idChinese.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,3 @@ async function analyse () {
}
}
</script>

0 comments on commit 5088075

Please sign in to comment.