更新 UI
This commit is contained in:
parent
826419fdbc
commit
9f6df6bbd8
@ -1,4 +1,5 @@
|
||||
# TODO
|
||||
|
||||
- [ ] CI 集成,将 dist 传输到指定服务器指定目录。
|
||||
- [x] CI 集成,将 dist 传输到指定服务器指定目录。
|
||||
- [x] 添加 SM2 算法
|
||||
|
||||
|
||||
474
src/App.tsx
474
src/App.tsx
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { VERSION } from './version'
|
||||
|
||||
import { sm3Digest, sm3Hmac } from './utils/algorithm/sm3'
|
||||
@ -7,9 +7,36 @@ import { hexToUtf8, utf8ToHex } from './utils/convert'
|
||||
|
||||
function App() {
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// SM3 状态
|
||||
const [sm3Message, setSm3Message] = useState('')
|
||||
const [sm3Result, setSm3Result] = useState('')
|
||||
@ -92,113 +119,280 @@ function App() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<h1>安全算法计算工具</h1>
|
||||
<div className="app" style={{ maxWidth: '800px', margin: '0 auto', padding: '20px', fontFamily: 'Arial, sans-serif', backgroundColor: '#121212', color: '#e0e0e0', minHeight: '100vh' }}>
|
||||
<h1 style={{ textAlign: 'center', color: '#f59e0b' }}>安全算法计算工具</h1>
|
||||
|
||||
<div className="tabs">
|
||||
<button
|
||||
className={`tab ${activeTab === 'sm3' ? 'active' : ''}`}
|
||||
onClick={() => setActiveTab('sm3')}
|
||||
>
|
||||
SM3
|
||||
</button>
|
||||
<button
|
||||
className={`tab ${activeTab === 'sm4' ? 'active' : ''}`}
|
||||
onClick={() => setActiveTab('sm4')}
|
||||
>
|
||||
SM4
|
||||
</button>
|
||||
<button
|
||||
className={`tab ${activeTab === 'convert' ? 'active' : ''}`}
|
||||
onClick={() => setActiveTab('convert')}
|
||||
>
|
||||
转换工具
|
||||
</button>
|
||||
</div>
|
||||
{/* 桌面端 Tab 选择 */}
|
||||
{!isMobile && (
|
||||
<div className="tabs" style={{ display: 'flex', borderBottom: '1px solid #333', marginBottom: '20px', backgroundColor: '#1e1e1e', borderRadius: '8px 8px 0 0', overflow: 'hidden' }}>
|
||||
<button
|
||||
className={`tab ${activeTab === 'sm3' ? 'active' : ''}`}
|
||||
onClick={() => handleTabChange('sm3')}
|
||||
style={{
|
||||
padding: '12px 24px',
|
||||
border: 'none',
|
||||
background: activeTab === 'sm3' ? '#333' : '#1e1e1e',
|
||||
cursor: 'pointer',
|
||||
fontSize: '16px',
|
||||
fontWeight: activeTab === 'sm3' ? 'bold' : 'normal',
|
||||
color: activeTab === 'sm3' ? '#f59e0b' : '#e0e0e0',
|
||||
outline: 'none',
|
||||
transition: 'all 0.3s ease',
|
||||
borderBottom: activeTab === 'sm3' ? '3px solid #f59e0b' : 'none'
|
||||
}}
|
||||
>
|
||||
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 面板 */}
|
||||
{activeTab === 'sm3' && (
|
||||
<div className="panel">
|
||||
<h2>SM3 算法</h2>
|
||||
<div className="panel" style={{ backgroundColor: '#1e1e1e', padding: '20px', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }}>
|
||||
<h2 style={{ color: '#f59e0b', marginBottom: '20px' }}>SM3 算法</h2>
|
||||
|
||||
<div className="form-group">
|
||||
<label>消息</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>消息</label>
|
||||
<textarea
|
||||
value={sm3Message}
|
||||
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 className="form-group">
|
||||
<label>SM3 结果</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>SM3 结果</label>
|
||||
<textarea
|
||||
value={sm3Result}
|
||||
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>
|
||||
|
||||
<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' }}>
|
||||
<label>HMAC 密钥</label>
|
||||
<div className="form-group" style={{ marginTop: '1.5rem', marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>HMAC 密钥</label>
|
||||
<input
|
||||
type="text"
|
||||
value={sm3HmacKey}
|
||||
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 className="form-group">
|
||||
<label>SM3 HMAC 结果</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>SM3 HMAC 结果</label>
|
||||
<textarea
|
||||
value={sm3HmacResult}
|
||||
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>
|
||||
|
||||
<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>
|
||||
)}
|
||||
|
||||
{/* SM4 面板 */}
|
||||
{activeTab === 'sm4' && (
|
||||
<div className="panel">
|
||||
<h2>SM4 算法</h2>
|
||||
<div className="panel" style={{ backgroundColor: '#1e1e1e', padding: '20px', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }}>
|
||||
<h2 style={{ color: '#f59e0b', marginBottom: '20px' }}>SM4 算法</h2>
|
||||
|
||||
<div className="form-group">
|
||||
<label>密钥 (16 字节 hex)</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>密钥 (16 字节 hex)</label>
|
||||
<input
|
||||
type="text"
|
||||
value={sm4Key}
|
||||
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 className="form-group">
|
||||
<label>IV (16 字节 hex, CBC/CFB/GCM 模式需要)</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>IV (16 字节 hex, CBC/CFB/GCM 模式需要)</label>
|
||||
<input
|
||||
type="text"
|
||||
value={sm4Iv}
|
||||
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 className="form-group">
|
||||
<label>模式</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>模式</label>
|
||||
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
|
||||
{['ecb', 'cbc', 'gcm'].map(mode => (
|
||||
<button
|
||||
key={mode}
|
||||
className={sm4Mode === mode ? 'primary' : ''}
|
||||
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()}
|
||||
</button>
|
||||
@ -206,14 +400,25 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>填充模式</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>填充模式</label>
|
||||
<div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
|
||||
{(['pkcs7', 'none'] as const).map(paddingMode => (
|
||||
<button
|
||||
key={paddingMode}
|
||||
className={sm4PaddingMode === paddingMode ? 'primary' : ''}
|
||||
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}
|
||||
</button>
|
||||
@ -221,73 +426,190 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>消息</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>消息</label>
|
||||
<textarea
|
||||
value={sm4Message}
|
||||
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 className="form-group">
|
||||
<label>加密结果</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>加密结果</label>
|
||||
<textarea
|
||||
value={sm4Encrypted}
|
||||
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 className="form-group">
|
||||
<label>解密结果</label>
|
||||
<div className="form-group" style={{ marginBottom: '15px' }}>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>解密结果</label>
|
||||
<textarea
|
||||
value={sm4Decrypted}
|
||||
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 className="button-group">
|
||||
<button onClick={handleEncryptSm4}>加密</button>
|
||||
<button onClick={handleDecryptSm4}>解密</button>
|
||||
<div className="button-group" style={{ display: 'flex', gap: '10px' }}>
|
||||
<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>
|
||||
)}
|
||||
|
||||
{/* 转换工具面板 */}
|
||||
{activeTab === 'convert' && (
|
||||
<div className="panel">
|
||||
<h2>Hex / UTF8 转换</h2>
|
||||
<div className="panel" style={{ backgroundColor: '#1e1e1e', padding: '20px', borderRadius: '8px', boxShadow: '0 2px 4px rgba(0, 0, 0, 0.3)' }}>
|
||||
<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 }}>
|
||||
<label>UTF8 输入</label>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>UTF8 输入</label>
|
||||
<textarea
|
||||
value={utf8Input}
|
||||
onChange={(e) => setUtf8Input(e.target.value)}
|
||||
placeholder="输入 UTF8 字符串"
|
||||
style={{ height: '200px' }}
|
||||
placeholder="输入 UTF8 字符串"
|
||||
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 className="form-group" style={{ flex: 1 }}>
|
||||
<label>Hex 输入</label>
|
||||
<label style={{ display: 'block', marginBottom: '5px', color: '#e0e0e0' }}>Hex 输入</label>
|
||||
<textarea
|
||||
value={hexInput}
|
||||
onChange={(e) => setHexInput(e.target.value)}
|
||||
placeholder="输入 hex 字符串"
|
||||
style={{ height: '200px' }}
|
||||
placeholder="输入 hex 字符串"
|
||||
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>
|
||||
)}
|
||||
|
||||
{/* 页脚 */}
|
||||
<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>版本号: {VERSION}</p>
|
||||
</footer>
|
||||
|
||||
@ -1 +1 @@
|
||||
export const VERSION = "V1.0-20260417022550";
|
||||
export const VERSION = "V1.0-20260417024927";
|
||||
Loading…
Reference in New Issue
Block a user