更新 UI
This commit is contained in:
parent
826419fdbc
commit
9f6df6bbd8
@ -1,4 +1,5 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
- [ ] CI 集成,将 dist 传输到指定服务器指定目录。
|
- [x] CI 集成,将 dist 传输到指定服务器指定目录。
|
||||||
|
- [x] 添加 SM2 算法
|
||||||
|
|
||||||
|
|||||||
450
src/App.tsx
450
src/App.tsx
@ -1,4 +1,4 @@
|
|||||||
import { useState } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { VERSION } from './version'
|
import { VERSION } from './version'
|
||||||
|
|
||||||
import { sm3Digest, sm3Hmac } from './utils/algorithm/sm3'
|
import { sm3Digest, sm3Hmac } from './utils/algorithm/sm3'
|
||||||
@ -7,6 +7,33 @@ import { hexToUtf8, utf8ToHex } from './utils/convert'
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [activeTab, setActiveTab] = useState('sm3')
|
const [activeTab, setActiveTab] = useState('sm3')
|
||||||
|
const [isMobile, setIsMobile] = useState(false)
|
||||||
|
const [mobileTab, setMobileTab] = useState('sm3')
|
||||||
|
|
||||||
|
// 检测是否为移动设备
|
||||||
|
useEffect(() => {
|
||||||
|
const checkMobile = () => {
|
||||||
|
setIsMobile(window.innerWidth < 768)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkMobile()
|
||||||
|
window.addEventListener('resize', checkMobile)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', checkMobile)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 处理移动设备的 tab 切换
|
||||||
|
const handleMobileTabChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
setMobileTab(e.target.value)
|
||||||
|
setActiveTab(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理桌面端的 tab 切换
|
||||||
|
const handleTabChange = (tab: string) => {
|
||||||
|
setActiveTab(tab)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -92,113 +119,280 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app">
|
<div className="app" style={{ maxWidth: '800px', margin: '0 auto', padding: '20px', fontFamily: 'Arial, sans-serif', backgroundColor: '#121212', color: '#e0e0e0', minHeight: '100vh' }}>
|
||||||
<h1>安全算法计算工具</h1>
|
<h1 style={{ textAlign: 'center', color: '#f59e0b' }}>安全算法计算工具</h1>
|
||||||
|
|
||||||
<div className="tabs">
|
{/* 桌面端 Tab 选择 */}
|
||||||
<button
|
{!isMobile && (
|
||||||
className={`tab ${activeTab === 'sm3' ? 'active' : ''}`}
|
<div className="tabs" style={{ display: 'flex', borderBottom: '1px solid #333', marginBottom: '20px', backgroundColor: '#1e1e1e', borderRadius: '8px 8px 0 0', overflow: 'hidden' }}>
|
||||||
onClick={() => setActiveTab('sm3')}
|
<button
|
||||||
>
|
className={`tab ${activeTab === 'sm3' ? 'active' : ''}`}
|
||||||
SM3
|
onClick={() => handleTabChange('sm3')}
|
||||||
</button>
|
style={{
|
||||||
<button
|
padding: '12px 24px',
|
||||||
className={`tab ${activeTab === 'sm4' ? 'active' : ''}`}
|
border: 'none',
|
||||||
onClick={() => setActiveTab('sm4')}
|
background: activeTab === 'sm3' ? '#333' : '#1e1e1e',
|
||||||
>
|
cursor: 'pointer',
|
||||||
SM4
|
fontSize: '16px',
|
||||||
</button>
|
fontWeight: activeTab === 'sm3' ? 'bold' : 'normal',
|
||||||
<button
|
color: activeTab === 'sm3' ? '#f59e0b' : '#e0e0e0',
|
||||||
className={`tab ${activeTab === 'convert' ? 'active' : ''}`}
|
outline: 'none',
|
||||||
onClick={() => setActiveTab('convert')}
|
transition: 'all 0.3s ease',
|
||||||
>
|
borderBottom: activeTab === 'sm3' ? '3px solid #f59e0b' : 'none'
|
||||||
转换工具
|
}}
|
||||||
</button>
|
>
|
||||||
</div>
|
SM3
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`tab ${activeTab === 'sm4' ? 'active' : ''}`}
|
||||||
|
onClick={() => handleTabChange('sm4')}
|
||||||
|
style={{
|
||||||
|
padding: '12px 24px',
|
||||||
|
border: 'none',
|
||||||
|
background: activeTab === 'sm4' ? '#333' : '#1e1e1e',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: activeTab === 'sm4' ? 'bold' : 'normal',
|
||||||
|
color: activeTab === 'sm4' ? '#f59e0b' : '#e0e0e0',
|
||||||
|
outline: 'none',
|
||||||
|
transition: 'all 0.3s ease',
|
||||||
|
borderBottom: activeTab === 'sm4' ? '3px solid #f59e0b' : 'none'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
SM4
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`tab ${activeTab === 'convert' ? 'active' : ''}`}
|
||||||
|
onClick={() => handleTabChange('convert')}
|
||||||
|
style={{
|
||||||
|
padding: '12px 24px',
|
||||||
|
border: 'none',
|
||||||
|
background: activeTab === 'convert' ? '#333' : '#1e1e1e',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: activeTab === 'convert' ? 'bold' : 'normal',
|
||||||
|
color: activeTab === 'convert' ? '#f59e0b' : '#e0e0e0',
|
||||||
|
outline: 'none',
|
||||||
|
transition: 'all 0.3s ease',
|
||||||
|
borderBottom: activeTab === 'convert' ? '3px solid #f59e0b' : 'none'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
转换工具
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 移动端下拉选择 */}
|
||||||
|
{isMobile && (
|
||||||
|
<div className="mobile-tab-selector" style={{ marginBottom: '20px' }}>
|
||||||
|
<select
|
||||||
|
value={mobileTab}
|
||||||
|
onChange={handleMobileTabChange}
|
||||||
|
className="mobile-select"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '12px',
|
||||||
|
fontSize: '16px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: '#1e1e1e',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
outline: 'none',
|
||||||
|
appearance: 'none',
|
||||||
|
cursor: 'pointer'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value="sm3" style={{ background: '#1e1e1e', color: '#e0e0e0' }}>SM3</option>
|
||||||
|
<option value="sm4" style={{ background: '#1e1e1e', color: '#e0e0e0' }}>SM4</option>
|
||||||
|
<option value="convert" style={{ background: '#1e1e1e', color: '#e0e0e0' }}>转换工具</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* SM3 面板 */}
|
{/* SM3 面板 */}
|
||||||
{activeTab === 'sm3' && (
|
{activeTab === 'sm3' && (
|
||||||
<div className="panel">
|
<div className="panel" style={{ backgroundColor: '#1e1e1e', padding: '20px', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }}>
|
||||||
<h2>SM3 算法</h2>
|
<h2 style={{ color: '#f59e0b', marginBottom: '20px' }}>SM3 算法</h2>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>消息</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>消息</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={sm3Message}
|
value={sm3Message}
|
||||||
onChange={(e) => setSm3Message(e.target.value)}
|
onChange={(e) => setSm3Message(e.target.value)}
|
||||||
placeholder="输入要计算的消息"
|
placeholder="输入要计算的消息"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical',
|
||||||
|
minHeight: '100px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>SM3 结果</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>SM3 结果</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={sm3Result}
|
value={sm3Result}
|
||||||
readOnly
|
readOnly
|
||||||
placeholder="SM3 计算结果将显示在这里"
|
placeholder="SM3 计算结果将显示在这里"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical',
|
||||||
|
minHeight: '100px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onClick={handleCalculateSm3}>计算 SM3</button>
|
<button
|
||||||
|
onClick={handleCalculateSm3}
|
||||||
|
style={{
|
||||||
|
padding: '10px 20px',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: '#f59e0b',
|
||||||
|
color: '#121212',
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'background 0.3s ease'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
计算 SM3
|
||||||
|
</button>
|
||||||
|
|
||||||
<div className="form-group" style={{ marginTop: '1.5rem' }}>
|
<div className="form-group" style={{ marginTop: '1.5rem', marginBottom: '15px' }}>
|
||||||
<label>HMAC 密钥</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>HMAC 密钥</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={sm3HmacKey}
|
value={sm3HmacKey}
|
||||||
onChange={(e) => setSm3HmacKey(e.target.value)}
|
onChange={(e) => setSm3HmacKey(e.target.value)}
|
||||||
placeholder="输入 HMAC 密钥 (hex)"
|
placeholder="输入 HMAC 密钥 (hex)"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>SM3 HMAC 结果</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>SM3 HMAC 结果</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={sm3HmacResult}
|
value={sm3HmacResult}
|
||||||
readOnly
|
readOnly
|
||||||
placeholder="SM3 HMAC 计算结果将显示在这里"
|
placeholder="SM3 HMAC 计算结果将显示在这里"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical',
|
||||||
|
minHeight: '100px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onClick={calculateSm3Hmac}>计算 SM3 HMAC</button>
|
<button
|
||||||
|
onClick={calculateSm3Hmac}
|
||||||
|
style={{
|
||||||
|
padding: '10px 20px',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: '#f59e0b',
|
||||||
|
color: '#121212',
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'background 0.3s ease'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
计算 SM3 HMAC
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* SM4 面板 */}
|
{/* SM4 面板 */}
|
||||||
{activeTab === 'sm4' && (
|
{activeTab === 'sm4' && (
|
||||||
<div className="panel">
|
<div className="panel" style={{ backgroundColor: '#1e1e1e', padding: '20px', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }}>
|
||||||
<h2>SM4 算法</h2>
|
<h2 style={{ color: '#f59e0b', marginBottom: '20px' }}>SM4 算法</h2>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>密钥 (16 字节 hex)</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>密钥 (16 字节 hex)</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={sm4Key}
|
value={sm4Key}
|
||||||
onChange={(e) => setSm4Key(e.target.value)}
|
onChange={(e) => setSm4Key(e.target.value)}
|
||||||
placeholder="输入 16 字节密钥 (32 位 hex)"
|
placeholder="输入 16 字节密钥 (32 位 hex)"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>IV (16 字节 hex, CBC/CFB/GCM 模式需要)</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>IV (16 字节 hex, CBC/CFB/GCM 模式需要)</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={sm4Iv}
|
value={sm4Iv}
|
||||||
onChange={(e) => setSm4Iv(e.target.value)}
|
onChange={(e) => setSm4Iv(e.target.value)}
|
||||||
placeholder="输入 16 字节 IV (32 位 hex)"
|
placeholder="输入 16 字节 IV (32 位 hex)"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>模式</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>模式</label>
|
||||||
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
|
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
|
||||||
{['ecb', 'cbc', 'gcm'].map(mode => (
|
{['ecb', 'cbc', 'gcm'].map(mode => (
|
||||||
<button
|
<button
|
||||||
key={mode}
|
key={mode}
|
||||||
className={sm4Mode === mode ? 'primary' : ''}
|
className={sm4Mode === mode ? 'primary' : ''}
|
||||||
onClick={() => setSm4Mode(mode)}
|
onClick={() => setSm4Mode(mode)}
|
||||||
|
style={{
|
||||||
|
padding: '8px 16px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: sm4Mode === mode ? '#f59e0b' : '#2d2d2d',
|
||||||
|
color: sm4Mode === mode ? '#121212' : '#e0e0e0',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontSize: '14px',
|
||||||
|
fontWeight: sm4Mode === mode ? 'bold' : 'normal',
|
||||||
|
transition: 'all 0.3s ease'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{mode.toUpperCase()}
|
{mode.toUpperCase()}
|
||||||
</button>
|
</button>
|
||||||
@ -206,14 +400,25 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>填充模式</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>填充模式</label>
|
||||||
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
|
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
|
||||||
{(['pkcs7', 'none'] as const).map(paddingMode => (
|
{(['pkcs7', 'none'] as const).map(paddingMode => (
|
||||||
<button
|
<button
|
||||||
key={paddingMode}
|
key={paddingMode}
|
||||||
className={sm4PaddingMode === paddingMode ? 'primary' : ''}
|
className={sm4PaddingMode === paddingMode ? 'primary' : ''}
|
||||||
onClick={() => setSm4PaddingMode(paddingMode)}
|
onClick={() => setSm4PaddingMode(paddingMode)}
|
||||||
|
style={{
|
||||||
|
padding: '8px 16px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: sm4PaddingMode === paddingMode ? '#f59e0b' : '#2d2d2d',
|
||||||
|
color: sm4PaddingMode === paddingMode ? '#121212' : '#e0e0e0',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontSize: '14px',
|
||||||
|
fontWeight: sm4PaddingMode === paddingMode ? 'bold' : 'normal',
|
||||||
|
transition: 'all 0.3s ease'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{paddingMode}
|
{paddingMode}
|
||||||
</button>
|
</button>
|
||||||
@ -221,73 +426,190 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>消息</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>消息</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={sm4Message}
|
value={sm4Message}
|
||||||
onChange={(e) => setSm4Message(e.target.value)}
|
onChange={(e) => setSm4Message(e.target.value)}
|
||||||
placeholder="输入要加密的消息"
|
placeholder="输入要加密的消息"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical',
|
||||||
|
minHeight: '100px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>加密结果</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>加密结果</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={sm4Encrypted}
|
value={sm4Encrypted}
|
||||||
onChange={(e) => setSm4Encrypted(e.target.value)}
|
onChange={(e) => setSm4Encrypted(e.target.value)}
|
||||||
placeholder="输入加密结果 (hex)"
|
placeholder="输入加密结果 (hex)"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical',
|
||||||
|
minHeight: '100px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||||
<label>解密结果</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>解密结果</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={sm4Decrypted}
|
value={sm4Decrypted}
|
||||||
readOnly
|
readOnly
|
||||||
placeholder="解密结果将显示在这里"
|
placeholder="解密结果将显示在这里"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical',
|
||||||
|
minHeight: '100px'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="button-group">
|
<div className="button-group" style={{ display: 'flex', gap: '10px' }}>
|
||||||
<button onClick={handleEncryptSm4}>加密</button>
|
<button
|
||||||
<button onClick={handleDecryptSm4}>解密</button>
|
onClick={handleEncryptSm4}
|
||||||
|
style={{
|
||||||
|
padding: '10px 20px',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: '#f59e0b',
|
||||||
|
color: '#121212',
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'background 0.3s ease',
|
||||||
|
flex: 1
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
加密
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handleDecryptSm4}
|
||||||
|
style={{
|
||||||
|
padding: '10px 20px',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: '#f59e0b',
|
||||||
|
color: '#121212',
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'background 0.3s ease',
|
||||||
|
flex: 1
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
解密
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 转换工具面板 */}
|
{/* 转换工具面板 */}
|
||||||
{activeTab === 'convert' && (
|
{activeTab === 'convert' && (
|
||||||
<div className="panel">
|
<div className="panel" style={{ backgroundColor: '#1e1e1e', padding: '20px', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }}>
|
||||||
<h2>Hex / UTF8 转换</h2>
|
<h2 style={{ color: '#f59e0b', marginBottom: '20px' }}>Hex / UTF8 转换</h2>
|
||||||
|
|
||||||
<div style={{ display: 'flex', gap: '1rem', marginBottom: '1rem' }}>
|
<div style={{ display: 'flex', gap: '1rem', marginBottom: '1rem', flexDirection: isMobile ? 'column' : 'row' }}>
|
||||||
<div className="form-group" style={{ flex: 1 }}>
|
<div className="form-group" style={{ flex: 1 }}>
|
||||||
<label>UTF8 输入</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>UTF8 输入</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={utf8Input}
|
value={utf8Input}
|
||||||
onChange={(e) => setUtf8Input(e.target.value)}
|
onChange={(e) => setUtf8Input(e.target.value)}
|
||||||
placeholder="输入 UTF8 字符串"
|
placeholder="输入 UTF8 字符串"
|
||||||
style={{ height: '200px' }}
|
style={{
|
||||||
|
height: '200px',
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<button onClick={handleUtf8ToHex} style={{ marginTop: '0.5rem' }}>UTF8 → Hex</button>
|
<button
|
||||||
|
onClick={handleUtf8ToHex}
|
||||||
|
style={{
|
||||||
|
marginTop: '0.5rem',
|
||||||
|
padding: '8px 16px',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: '#f59e0b',
|
||||||
|
color: '#121212',
|
||||||
|
fontSize: '14px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'background 0.3s ease'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
UTF8 → Hex
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group" style={{ flex: 1 }}>
|
<div className="form-group" style={{ flex: 1 }}>
|
||||||
<label>Hex 输入</label>
|
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>Hex 输入</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={hexInput}
|
value={hexInput}
|
||||||
onChange={(e) => setHexInput(e.target.value)}
|
onChange={(e) => setHexInput(e.target.value)}
|
||||||
placeholder="输入 hex 字符串"
|
placeholder="输入 hex 字符串"
|
||||||
style={{ height: '200px' }}
|
style={{
|
||||||
|
height: '200px',
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px',
|
||||||
|
border: '1px solid #333',
|
||||||
|
borderRadius: '4px',
|
||||||
|
backgroundColor: '#2d2d2d',
|
||||||
|
color: '#e0e0e0',
|
||||||
|
fontSize: '14px',
|
||||||
|
resize: 'vertical'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<button onClick={handleHexToUtf8} style={{ marginTop: '0.5rem' }}>UTF8 ← Hex</button>
|
<button
|
||||||
|
onClick={handleHexToUtf8}
|
||||||
|
style={{
|
||||||
|
marginTop: '0.5rem',
|
||||||
|
padding: '8px 16px',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
background: '#f59e0b',
|
||||||
|
color: '#121212',
|
||||||
|
fontSize: '14px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: 'pointer',
|
||||||
|
transition: 'background 0.3s ease'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
UTF8 ← Hex
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 页脚 */}
|
{/* 页脚 */}
|
||||||
<footer style={{ marginTop: '2rem', padding: '1rem', borderTop: '1px solid #ccc', textAlign: 'center' }}>
|
<footer style={{ marginTop: '2rem', padding: '1rem', borderTop: '1px solid #333', textAlign: 'center', color: '#e0e0e0' }}>
|
||||||
<p>© 2026 安全算法计算工具</p>
|
<p>© 2026 安全算法计算工具</p>
|
||||||
<p>版本号: {VERSION}</p>
|
<p>版本号: {VERSION}</p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
export const VERSION = "V1.0-20260417022550";
|
export const VERSION = "V1.0-20260417024927";
|
||||||
Loading…
Reference in New Issue
Block a user