下载地址:http://lanzou.com.cn/ia2f1a9d3

📁 output/appxujisuanmoxingaiban/
├── 📄 README.md202 B
├── 📄 pom.xml1.3 KB
├── 📄 package.json698 B
├── 📄 assets/Worker.js3.8 KB
├── 📄 roles/Processor.js3.2 KB
├── 📄 roles/Adapter.php4.1 KB
├── 📄 config/Handler.json698 B
├── 📄 roles/Helper.py5 KB
├── 📄 filters/Builder.js4 KB
├── 📄 page/Server.php3.8 KB
├── 📄 assets/Listener.py4.8 KB
├── 📄 page/Loader.py5.2 KB
├── 📄 src/main/java/Cache.java7 KB
├── 📄 src/main/java/Scheduler.java4.2 KB
├── 📄 src/main/java/Registry.java4.7 KB
├── 📄 src/main/java/Transformer.java7.1 KB
├── 📄 assets/Repository.sql3.1 KB
├── 📄 config/Wrapper.xml1.4 KB
├── 📄 lib/Buffer.jar659 B
├── 📄 filters/Factory.js3.2 KB
├── 📄 roles/Dispatcher.js3.9 KB
├── 📄 assets/Parser.php2.8 KB
├── 📄 config/Provider.json698 B
├── 📄 roles/Controller.py4.5 KB
项目编译入口:
Project Structure
Project : 余额app虚拟计算模型ai版
Folder : appxujisuanmoxingaiban
Files : 26
Size : 82.8 KB
Generated: 2026-03-23 19:27:02
appxujisuanmoxingaiban/
├── README.md [202 B]
├── assets/
│ ├── Listener.py [4.8 KB]
│ ├── Parser.php [2.8 KB]
│ ├── Repository.sql [3.1 KB]
│ └── Worker.js [3.8 KB]
├── config/
│ ├── Handler.json [698 B]
│ ├── Provider.json [698 B]
│ └── Wrapper.xml [1.4 KB]
├── filters/
│ ├── Builder.js [4 KB]
│ └── Factory.js [3.2 KB]
├── lib/
│ └── Buffer.jar [659 B]
├── package.json [698 B]
├── page/
│ ├── Loader.py [5.2 KB]
│ ├── Proxy.js [3 KB]
│ └── Server.php [3.8 KB]
├── pom.xml [1.3 KB]
├── roles/
│ ├── Adapter.php [4.1 KB]
│ ├── Controller.py [4.5 KB]
│ ├── Dispatcher.js [3.9 KB]
│ ├── Helper.py [5 KB]
│ └── Processor.js [3.2 KB]
└── src/
├── main/
│ ├── java/
│ │ ├── Cache.java [7 KB]
│ │ ├── Registry.java [4.7 KB]
│ │ ├── Scheduler.java [4.2 KB]
│ │ └── Transformer.java [7.1 KB]
│ └── resources/
└── test/
└── java/
import hashlib
import secrets
import time
import json
import os
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass, field, asdict
from enum import Enum
import uuid
===================== 枚举与常量 =====================
class TransactionType(Enum):
"""交易类型枚举"""
DEPOSIT = "存款"
WITHDRAWAL = "取款"
TRANSFER = "转账"
RECEIVE = "收款"
FEE = "手续费"
INTEREST = "利息"
class AccountStatus(Enum):
"""账户状态"""
ACTIVE = "正常"
FROZEN = "冻结"
CLOSED = "已注销"
SUSPENDED = "挂失"
class SecurityLevel(Enum):
"""安全等级"""
STANDARD = 1
HIGH = 2
MILITARY = 3
===================== 数据模型 =====================
@dataclass
class Transaction:
"""交易记录数据类"""
transaction_id: str
account_number: str
type: TransactionType
amount: float
balance_after: float
counterparty: str # 对手方账号或描述
timestamp: datetime
signature: str # 交易签名(防篡改)
description: str = ""
def to_dict(self) -> dict:
"""转换为字典"""
data = asdict(self)
data['type'] = self.type.value
data['timestamp'] = self.timestamp.isoformat()
return data
@classmethod
def from_dict(cls, data: dict):
"""从字典恢复"""
data['type'] = TransactionType(data['type'])
data['timestamp'] = datetime.fromisoformat(data['timestamp'])
return cls(**data)
@dataclass
class BankAccount:
"""银行账户数据类"""
account_number: str
owner_name: str
owner_id: str # 身份证号/护照号
pin_hash: str # 密码哈希 (SHA-256)
balance: float
currency: str = "CNY"
status: AccountStatus = AccountStatus.ACTIVE
created_at: datetime = field(default_factory=datetime.now)
security_level: SecurityLevel = SecurityLevel.STANDARD
daily_transfer_limit: float = 50000.0
daily_transferred: float = 0.0
last_reset_date: str = field(default_factory=lambda: datetime.now().date().isoformat())
transactions: List[Transaction] = field(default_factory=list)
failed_login_attempts: int = 0
locked_until: Optional[datetime] = None
two_factor_enabled: bool = False
two_factor_secret: Optional[str] = None # 模拟2FA密钥
def to_dict(self) -> dict:
"""序列化账户(排除敏感哈希)"""
data = {
'account_number': self.account_number,
'owner_name': self.owner_name,
'owner_id': self.owner_id[:3] + "***" + self.owner_id[-4:] if len(self.owner_id) > 7 else "***",
'balance': self.balance,
'currency': self.currency,
'status': self.status.value,
'created_at': self.created_at.isoformat(),
'security_level': self.security_level.value,
'daily_transfer_limit': self.daily_transfer_limit,
'daily_transferred': self.daily_transferred,
'last_reset_date': self.last_reset_date,
'two_factor_enabled': self.two_factor_enabled
}
return data
===================== 安全工具类 =====================
class CypherSecurity:
"""Cypher安全引擎 - 哈希、令牌、签名生成"""
@staticmethod
def hash_pin(pin: str, salt: Optional[str] = None) -> str:
"""使用SHA-256加盐哈希PIN码"""
if salt is None:
salt = secrets.token_hex(16)
combined = pin + salt
hash_val = hashlib.sha256(combined.encode()).hexdigest()
return f"{salt}:{hash_val}"
@staticmethod
def verify_pin(pin: str, stored_hash: str) -> bool:
"""验证PIN码"""
try:
salt, hash_val = stored_hash.split(':')
combined = pin + salt
return hashlib.sha256(combined.encode()).hexdigest() == hash_val
except Exception:
return False
@staticmethod
def generate_session_token(account_number: str) -> str:
"""生成会话令牌 (JWT风格模拟)"""
payload = f"{account_number}:{int(time.time())}:{secrets.token_hex(8)}"
signature = hashlib.sha256(payload.encode()).hexdigest()[:32]
return f"{payload}:{signature}"
@staticmethod
def verify_session_token(token: str, account_number: str, max_age_seconds: int = 600) -> bool:
"""验证会话令牌(时效10分钟)"""
try:
parts = token.split(':')
if len(parts) != 4:
return False
token_acc = parts[0]
timestamp = int(parts[1])
nonce = parts[2]
signature = parts[3]
if token_acc != account_number:
return False
if time.time() - timestamp > max_age_seconds:
return False
expected = hashlib.sha256(f"{token_acc}:{timestamp}:{nonce}".encode()).hexdigest()[:32]
return signature == expected
except Exception:
return False
@staticmethod
def sign_transaction(transaction_data: dict) -> str:
"""为交易生成防篡改签名"""
# 按顺序拼接关键字段
content = f"{transaction_data.get('transaction_id')}|{transaction_data.get('account_number')}|{transaction_data.get('amount')}|{transaction_data.get('timestamp')}|{transaction_data.get('counterparty')}"
return hashlib.sha512(content.encode()).hexdigest()[:64]
@staticmethod
def generate_otp() -> str:
"""生成6位一次性密码(模拟2FA)"""
return f"{secrets.randbelow(1000000):06d}"
===================== 银行核心引擎 =====================
class CypherBankEngine:
"""赛博银行核心 - 管理所有账户和交易"""
def __init__(self, data_file: str = "bank_data.json"):
self.data_file = data_file
self.accounts: Dict[str, BankAccount] = {}
self.active_sessions: Dict[str, Tuple[str, float]] = {} # token -> (account, expiry)
self.load_data()
def load_data(self):
"""从JSON文件加载账户数据"""
if os.path.exists(self.data_file):
try:
with open(self.data_file, 'r', encoding='utf-8') as f:
data = json.load(f)
for acc_num, acc_data in data.items():
# 重建交易列表
transactions = []
for tx_data in acc_data.get('transactions', []):
transactions.append(Transaction.from_dict(tx_data))
# 重建账户
pin_hash = acc_data['pin_hash']
account = BankAccount(
account_number=acc_data['account_number'],
owner_name=acc_data['owner_name'],
owner_id=acc_data['owner_id'],
pin_hash=pin_hash,
balance=acc_data['balance'],
currency=acc_data.get('currency', 'CNY'),
status=AccountStatus(acc_data.get('status', 'ACTIVE')),
created_at=datetime.fromisoformat(acc_data['created_at']),
security_level=SecurityLevel(acc_data.get('security_level', 1)),
daily_transfer_limit=acc_data.get('daily_transfer_limit', 50000.0),
daily_transferred=acc_data.get('daily_transferred', 0.0),
last_reset_date=acc_data.get('last_reset_date', datetime.now().date().isoformat()),
transactions=transactions,
failed_login_attempts=acc_data.get('failed_login_attempts', 0),
locked_until=datetime.fromisoformat(acc_data['locked_until']) if acc_data.get('locked_until') else None,
two_factor_enabled=acc_data.get('two_factor_enabled', False),
two_factor_secret=acc_data.get('two_factor_secret')
)
self.accounts[acc_num] = account
print(f"[系统] 已加载 {len(self.accounts)} 个账户")
except Exception as e:
print(f"[警告] 加载数据失败: {e}, 使用空数据库")
self._create_demo_accounts()
else:
self._create_demo_accounts()
self.save_data()
def _create_demo_accounts(self):
"""创建演示账户"""
# 账户1: 普通用户
pin_hash = CypherSecurity.hash_pin("123456")
acc1 = BankAccount(
account_number="6228480012345678",
owner_name="张三",
owner_id="11010119900307663X",
pin_hash=pin_hash,
balance=52800.50,
daily_transfer_limit=20000.0
)
# 添加几条示例交易
acc1.transactions.append(Transaction(
transaction_id=str(uuid.uuid4()),
account_number=acc1.account_number,
type=TransactionType.DEPOSIT,
amount=50000.0,
balance_after=50000.0,
counterparty="工资代发",
timestamp=datetime.now() - timedelta(days=30),
signature="",
description="1月工资"
))
acc1.transactions.append(Transaction(
transaction_id=str(uuid.uuid4()),
account_number=acc1.account_number,
type=TransactionType.TRANSFER,
amount=1200.0,
balance_after=48800.0,
counterparty="6228480098765432",
timestamp=datetime.now() - timedelta(days=15),
signature="",
description="房租转账"
))
# 账户2: 高安全账户
pin_hash2 = CypherSecurity.hash_pin("888888")
acc2 = BankAccount(
account_number="6228480055556666",
owner_name="李四",
owner_id="310101199512121234",
pin_hash=pin_hash2,
balance=1250000.00,
security_level=SecurityLevel.HIGH,
daily_transfer_limit=100000.0,
two_factor_enabled=True,
two_factor_secret=secrets.token_hex(16)
)
self.accounts[acc1.account_number] = acc1
self.accounts[acc2.account_number] = acc2
print("[演示] 已创建演示账户: 张三(密码123456), 李四(密码888888)")
def save_data(self):
"""保存所有账户数据到JSON"""
try:
data = {}
for acc_num, account in self.accounts.items():
acc_dict = {
'account_number': account.account_number,
'owner_name': account.owner_name,
'owner_id': account.owner_id,
'pin_hash': account.pin_hash,
'balance': account.balance,
'currency': account.currency,
'status': account.status.value,
'created_at': account.created_at.isoformat(),
'security_level': account.security_level.value,
'daily_transfer_limit': account.daily_transfer_limit,
'daily_transferred': account.daily_transferred,
'last_reset_date': account.last_reset_date,
'failed_login_attempts': account.failed_login_attempts,
'locked_until': account.locked_until.isoformat() if account.locked_until else None,
'two_factor_enabled': account.two_factor_enabled,
'two_factor_secret': account.two_factor_secret,
'transactions': [tx.to_dict() for tx in account.transactions]
}
data[acc_num] = acc_dict
with open(self.data_file, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print("[系统] 数据已保存")
except Exception as e:
print(f"[错误] 保存失败: {e}")
def reset_daily_limit_if_needed(self, account: BankAccount):
"""重置每日转账额度"""
today = datetime.now().date().isoformat()
if account.last_reset_date != today:
account.daily_transferred = 0.0
account.last_reset_date = today
def login(self, account_number: str, pin: str, otp: Optional[str] = None) -> Tuple[bool, str, Optional[str]]:
"""
用户登录
返回: (成功标志, 消息, 会话令牌)
"""
account = self.accounts.get(account_number)
if not account:
return False, "账户不存在", None
# 检查账户状态
if account.status != AccountStatus.ACTIVE:
return False, f"账户状态异常: {account.status.value}", None
# 检查是否被临时锁定
if account.locked_until and datetime.now() < account.locked_until:
remain = (account.locked_until - datetime.now()).seconds // 60
return False, f"账户已被锁定, 请{remain}分钟后重试", None
# 验证PIN
if not CypherSecurity.verify_pin(pin, account.pin_hash):
account.failed_login_attempts += 1
if account.failed_login_attempts >= 5:
# 锁定30分钟
account.locked_until = datetime.now() + timedelta(minutes=30)
self.save_data()
return False, "密码错误次数过多, 账户已锁定30分钟", None
self.save_data()
return False, f"密码错误, 剩余尝试次数: {5 - account.failed_login_attempts}", None
# 2FA验证
if account.two_factor_enabled:
if not otp:
# 模拟发送OTP
fake_otp = CypherSecurity.generate_otp()
print(f"[2FA模拟] 向用户 {account.owner_name} 发送验证码: {fake_otp}")
# 这里简单将OTP存到account的一个临时属性 (演示用)
account._temp_otp = fake_otp
return False, "需要两步验证, 请输入短信验证码", None
elif not hasattr(account, '_temp_otp') or otp != account._temp_otp:
return False, "验证码错误", None
# 验证通过, 清除临时OTP
del account._temp_otp
# 登录成功, 重置失败计数
account.failed_login_attempts = 0
account.locked_until = None
session_token = CypherSecurity.generate_session_token(account_number)
self.active_sessions[session_token] = (account_number, time.time() + 3600) # 1小时有效期
self.save_data()
return True, "登录成功", session_token
def logout(self, session_token: str):
"""登出"""
if session_token in self.active_sessions:
del self.active_sessions[session_token]
def validate_session(self, session_token: str) -> Optional[BankAccount]:
"""验证会话, 返回账户对象"""
if session_token not in self.active_sessions:
return None
acc_num, expiry = self.active_sessions[session_token]
if time.time() > expiry:
del self.active_sessions[session_token]
return None
# 额外用token内容验证
if not CypherSecurity.verify_session_token(session_token, acc_num, max_age_seconds=3600):
del self.active_sessions[session_token]
return None
return self.accounts.get(acc_num)
def get_account_balance(self, account: BankAccount) -> float:
"""查询余额"""
return account.balance
def get_transaction_history(self, account: BankAccount, limit: int = 20) -> List[Transaction]:
"""获取交易历史, 按时间倒序"""
sorted_tx = sorted(account.transactions, key=lambda x: x.timestamp, reverse=True)
return sorted_tx[:limit]
def transfer(self, from_account: BankAccount, to_account_number: str, amount: float,
description: str = "", session_token: str = None) -> Tuple[bool, str]:
"""
转账核心逻辑
返回: (成功, 消息)
"""
# 验证会话 (传递进来保证已校验)
if not session_token or not self.validate_session(session_token):
return False, "会话无效, 请重新登录"
# 基本校验
if amount <= 0:
return False, "转账金额必须大于0"
# 检查目标账户是否存在
to_account = self.accounts.get(to_account_number)
if not to_account:
return False, "收款账户不存在"
if to_account.status != AccountStatus.ACTIVE:
return False, "收款账户状态异常"
# 检查余额
if from_account.balance < amount:
return False, "余额不足"
# 每日限额检查
self.reset_daily_limit_if_needed(from_account)
if from_account.daily_transferred + amount > from_account.daily_transfer_limit:
remaining = from_account.daily_transfer_limit - from_account.daily_transferred
return False, f"超出每日转账限额, 今日剩余额度: {remaining:.2f}"
# 高安全等级可能需要额外签名 (模拟)
if from_account.security_level == SecurityLevel.HIGH and amount > 50000:
# 实际场景需二次确认,这里简化模拟签名
print(f"[高安全] 大额转账 {amount} 需额外验证, 模拟通过")
# 执行转账 (原子操作)
from_account.balance -= amount
to_account.balance += amount
# 更新每日已转额度
from_account.daily_transferred += amount
# 创建交易记录(转出方)
tx_id_out = str(uuid.uuid4())
timestamp = datetime.now()
tx_out = Transaction(
transaction_id=tx_id_out,
account_number=from_account.account_number,
type=TransactionType.TRANSFER,
amount=-amount, # 负数表示支出
balance_after=from_account.balance,
counterparty=to_account_number,
timestamp=timestamp,
signature="",
description=description or f"转账至{to_account.owner_name}"
)
# 生成签名
tx_dict = tx_out.to_dict()
tx_out.signature = CypherSecurity.sign_transaction(tx_dict)
from_account.transactions.append(tx_out)
# 收款方记录
tx_id_in = str(uuid.uuid4())
tx_in = Transaction(
transaction_id=tx_id_in,
account_number=to_account.account_number,
type=TransactionType.RECEIVE,
amount=amount,
balance_after=to_account.balance,
counterparty=from_account.account_number,
timestamp=timestamp,
signature="",
description=description or f"来自{from_account.owner_name}"
)
tx_in.signature = CypherSecurity.sign_transaction(tx_in.to_dict())
to_account.transactions.append(tx_in)
# 保存数据
self.save_data()
return True, f"转账成功! 金额: {amount:.2f} {from_account.currency}, 交易ID: {tx_id_out[:8]}"
def deposit(self, account: BankAccount, amount: float, description: str = "") -> Tuple[bool, str]:
"""存款 (模拟现金/电子存入)"""
if amount <= 0:
return False, "存款金额必须大于0"
account.balance += amount
tx = Transaction(
transaction_id=str(uuid.uuid4()),
account_number=account.account_number,
type=TransactionType.DEPOSIT,
amount=amount,
balance_after=account.balance,
counterparty="现金存入/电子渠道",
timestamp=datetime.now(),
signature="",
description=description or "现金存款"
)
tx.signature = CypherSecurity.sign_transaction(tx.to_dict())
account.transactions.append(tx)
self.save_data()
return True, f"存款成功! 存入 {amount:.2f}, 当前余额 {account.balance:.2f}"
def withdraw(self, account: BankAccount, amount: float, description: str = "") -> Tuple[bool, str]:
"""取款"""
if amount <= 0:
return False, "取款金额必须大于0"
if account.balance < amount:
return False, "余额不足"
account.balance -= amount
tx = Transaction(
transaction_id=str(uuid.uuid4()),
account_number=account.account_number,
type=TransactionType.WITHDRAWAL,
amount=-amount,
balance_after=account.balance,
counterparty="ATM/柜面",
timestamp=datetime.now(),
signature="",
description=description or "现金取款"
)
tx.signature = CypherSecurity.sign_transaction(tx.to_dict())
account.transactions.append(tx)
self.save_data()
return True, f"取款成功! 取出 {amount:.2f}, 剩余 {account.balance:.2f}"
def change_pin(self, account: BankAccount, old_pin: str, new_pin: str) -> Tuple[bool, str]:
"""修改密码"""
if not CypherSecurity.verify_pin(old_pin, account.pin_hash):
return False, "原密码错误"
if len(new_pin) < 4 or len(new_pin) > 8 or not new_pin.isdigit():
return False, "新密码必须为4-8位数字"
account.pin_hash = CypherSecurity.hash_pin(new_pin)
self.save_data()
return True, "密码修改成功"
def get_account_info(self, account: BankAccount) -> dict:
"""获取账户概要信息"""
return account.to_dict()
===================== 模拟APP前端界面 (CLI交互) =====================
class BankAppSimulator:
"""银行APP模拟器主界面 - 赛博风格终端"""
def __init__(self):
self.engine = CypherBankEngine()
self.current_session = None
self.current_account = None
def clear_screen(self):
"""清屏模拟"""
os.system('cls' if os.name == 'nt' else 'clear')
print("\n" + "=" * 60)
print(" 🏦 CYPHER BANK · 安全银行模拟器 v2.0 [开源模型]")
print("=" * 60)
def display_main_menu(self):
"""主菜单"""
print("\n📱 主菜单:")
print("1. 登录账户")
print("2. 关于本系统")
print("0. 退出")
def display_account_menu(self):
"""账户操作菜单"""
print("\n💳 账户操作:")
print("1. 查询余额")
print("2. 交易记录")
print("3. 转账汇款")
print("4. 存款(模拟)")
print("5. 取款(模拟)")
print("6. 修改密码")
print("7. 账户详情")
print("8. 安全登出")
print("0. 返回主菜单")
def login_flow(self):
"""登录流程"""
print("\n🔐 登录系统")
acc_num = input("请输入账号: ").strip()
pin = input("请输入6位PIN密码: ").strip()
# 检查是否需要2FA
success, msg, token = self.engine.login(acc_num, pin, otp=None)
if success:
self.current_session = token
self.current_account = self.engine.validate_session(token)
print(f"✅ {msg}")
time.sleep(1)
return True
elif "需要两步验证" in msg:
print(f"⚠️ {msg}")
otp_input = input("请输入6位验证码: ").strip()
success2, msg2, token2 = self.engine.login(acc_num, pin, otp=otp_input)
if success2:
self.current_session = token2
self.current_account = self.engine.validate_session(token2)
print(f"✅ {msg2}")
time.sleep(1)
return True
else:
print(f"❌ {msg2}")
input("按回车继续...")
return False
else:
print(f"❌ {msg}")
input("按回车继续...")
return False
def run_account_services(self):
"""运行账户服务"""
while True:
self.clear_screen()
if not self.current_account:
break
owner = self.current_account.owner_name
print(f"\n👤 欢迎, {owner} | 账户: {self.current_account.account_number[-4:]}")
self.display_account_menu()
choice = input("\n请选择操作: ").strip()
if choice == "1":
self.show_balance()
elif choice == "2":
self.show_transactions()
elif choice == "3":
self.do_transfer()
elif choice == "4":
self.do_deposit()
elif choice == "5":
self.do_withdraw()
elif choice == "6":
self.change_pin()
elif choice == "7":
self.show_account_details()
elif choice == "8":
self.logout()
break
elif choice == "0":
self.logout()
break
else:
print("无效选项")
time.sleep(1)
def show_balance(self):
"""显示余额"""
bal = self.engine.get_account_balance(self.current_account)
print(f"\n💰 当前余额: {bal:.2f} {self.current_account.currency}")
input("\n按回车返回...")
def show_transactions(self):
"""显示交易记录"""
print("\n📜 最近交易记录:")
txs = self.engine.get_transaction_history(self.current_account, limit=10)
if not txs:
print("暂无交易记录")
else:
for tx in txs:
amount_str = f"{tx.amount:+.2f}" if isinstance(tx.amount, (int, float)) else str(tx.amount)
print(f"{tx.timestamp.strftime('%Y-%m-%d %H:%M')} | {tx.type.value:6s} | {amount_str:>10} | {tx.counterparty:15} | {tx.description}")
input("\n按回车返回...")
def do_transfer(self):
"""执行转账"""
print("\n💸 转账汇款")
to_acc = input("请输入收款账号: ").strip()
try:
amount = float(input("请输入转账金额: "))
except ValueError:
print("金额格式错误")
input("按回车返回...")
return
desc = input("请输入备注(可选): ").strip()
success, msg = self.engine.transfer(self.current_account, to_acc, amount, desc, self.current_session)
print(f"\n{'✅' if success else '❌'} {msg}")
input("按回车返回...")
def do_deposit(self):
"""存款"""
try:
amount = float(input("请输入存款金额: "))
except ValueError:
print("金额无效")
return
success, msg = self.engine.deposit(self.current_account, amount, "APP存款")
print(f"\n{msg}")
input("按回车返回...")
def do_withdraw(self):
"""取款"""
try:
amount = float(input("请输入取款金额: "))
except ValueError:
print("金额无效")
return
success, msg = self.engine.withdraw(self.current_account, amount, "APP取款")
print(f"\n{msg}")
input("按回车返回...")
def change_pin(self):
"""修改密码"""
old = input("请输入原密码: ").strip()
new = input("请输入新密码(4-8位数字): ").strip()
confirm = input("确认新密码: ").strip()
if new != confirm:
print("两次输入不一致")
input("按回车返回...")
return
success, msg = self.engine.change_pin(self.current_account, old, new)
print(f"\n{msg}")
input("按回车返回...")
def show_account_details(self):
"""账户详情"""
info = self.engine.get_account_info(self.current_account)
print("\n🏦 账户详细信息:")
for k, v in info.items():
print(f" {k}: {v}")
input("\n按回车返回...")
def logout(self):
"""登出"""
if self.current_session:
self.engine.logout(self.current_session)
self.current_session = None
self.current_account = None
print("✅ 已安全登出")
time.sleep(1)
def about(self):
"""关于"""
print("\n📡 Cypher Bank 模拟器 - 开源项目")
print("基于SHA-256哈希、会话令牌、交易签名等安全模型")
print("演示账号: 6228480012345678 / 123456")
print("高安全账号: 6228480055556666 / 888888 (需2FA验证码)")
print("所有数据持久化保存在 bank_data.json")
input("\n按回车返回...")
def run(self):
"""主循环"""
while True:
self.clear_screen()
self.display_main_menu()
choice = input("请选择: ").strip()
if choice == "1":
if self.login_flow():
self.run_account_services()
elif choice == "2":
self.about()
elif choice == "0":
print("\n感谢使用Cypher银行模拟器,再见!")
self.engine.save_data()
break
else:
print("无效选项")
time.sleep(1)
===================== 程序入口 =====================
if name == "main":
app = BankAppSimulator()
app.run()