oxygenxml.oxygen_18.1 生成KEY代码

本文介绍了一个使用Java实现的加密签名生成器,该生成器基于DSA算法为指定的注册名和公司名生成加密许可字符串,并对其进行签名。文章详细展示了如何使用PKCS8EncodedKeySpec和KeyFactory来生成私钥,以及如何利用Signature类进行SHA1withDSA签名。
  1. import java.io.BufferedReader;  
  2. import java.io.IOException;  
  3. import java.io.InputStreamReader;  
  4. import java.io.PrintStream;  
  5. import java.security.KeyFactory;  
  6. import java.security.NoSuchAlgorithmException;  
  7. import java.security.PrivateKey;  
  8. import java.security.Signature;  
  9. import java.security.spec.InvalidKeySpecException;  
  10. import java.security.spec.PKCS8EncodedKeySpec;  
  11. import java.text.SimpleDateFormat;  
  12. import java.util.Date;  
  13. import java.util.Locale;  
  14. import org.apache.commons.codec.binary.Base64;  
  15.   
  16. public class Keygen {  
  17.     private static SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyyy", Locale.US);  
  18.   
  19.     private static final byte[] privateKeyData = { 48, -126, 1, 76, 2, 1, 0, 48, -126, 1, 44, 6, 7, 42, -122, 72, -50, 56, 4, 1, 48, -126, 1, 31, 2,  
  20.             -127, -127, 0, -3, 127, 83, -127, 29, 117, 18, 41, 82, -33, 74, -100, 46, -20, -28, -25, -10, 17, -73, 82, 60, -17, 68, 0, -61, 30, 63,  
  21.             -128, -74, 81, 38, 105, 69, 93, 64, 34, 81, -5, 89, 61, -115, 88, -6, -65, -59, -11, -70, 48, -10, -53, -101, 85, 108, -41, -127, 59,  
  22.             -128, 29, 52, 111, -14, 102, 96, -73, 107, -103, 80, -91, -92, -97, -97, -24, 4, 123, 16, 34, -62, 79, -69, -87, -41, -2, -73, -58, 27,  
  23.             -8, 59, 87, -25, -58, -88, -90, 21, 15, 4, -5, -125, -10, -45, -59, 30, -61, 2, 53, 84, 19, 90, 22, -111, 50, -10, 117, -13, -82, 43, 97,  
  24.             -41, 42, -17, -14, 34, 3, 25, -99, -47, 72, 1, -57, 2, 21, 0, -105, 96, 80, -113, 21, 35, 11, -52, -78, -110, -71, -126, -94, -21, -124,  
  25.             11, -16, 88, 28, -11, 2, -127, -127, 0, -9, -31, -96, -123, -42, -101, 61, -34, -53, -68, -85, 92, 54, -72, 87, -71, 121, -108, -81, -69,  
  26.             -6, 58, -22, -126, -7, 87, 76, 11, 61, 7, -126, 103, 81, 89, 87, -114, -70, -44, 89, 79, -26, 113, 7, 16, -127, -128, -76, 73, 22, 113,  
  27.             35, -24, 76, 40, 22, 19, -73, -49, 9, 50, -116, -56, -90, -31, 60, 22, 122, -117, 84, 124, -115, 40, -32, -93, -82, 30, 43, -77, -90,  
  28.             117, -111, 110, -93, 127, 11, -6, 33, 53, 98, -15, -5, 98, 122, 1, 36, 59, -52, -92, -15, -66, -88, 81, -112, -119, -88, -125, -33, -31,  
  29.             90, -27, -97, 6, -110, -117, 102, 94, -128, 123, 85, 37, 100, 1, 76, 59, -2, -49, 73, 42, 4, 23, 2, 21, 0, -106, -49, 66, -124, -79, -94,  
  30.             -48, -108, 26, -46, -57, -110, -117, 14, -38, 1, -77, -127, 0, 14 };  
  31.     private String registrationName;  
  32.     private String company;  
  33.   
  34.     private static PrivateKey getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException {  
  35.         PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyData);  
  36.         return KeyFactory.getInstance("DSA").generatePrivate(pKCS8EncodedKeySpec);  
  37.     }  
  38.   
  39.     private static String convertString(String _string) {  
  40.         StringBuffer stringBuffer = new StringBuffer(_string);  
  41.         int length = stringBuffer.length();  
  42.         for (int i = 0; i < length; ++i) {  
  43.             if ("BADCEFGHIJKLNMOPQRSTUVWXZY0123456789 _-.@".indexOf(Character.toUpperCase(stringBuffer.charAt(i))) != -1)  
  44.                 continue;  
  45.             stringBuffer.setCharAt(i, '_');  
  46.         }  
  47.         return stringBuffer.toString();  
  48.     }  
  49.   
  50.     private static String inputString(BufferedReader _bufferedReader, String _message) throws IOException {  
  51.         String inputLine = null;  
  52.         do {  
  53.             System.out.print(_message);  
  54.             System.out.flush();  
  55.             inputLine = _bufferedReader.readLine();  
  56.         } while ((inputLine == null) || (inputLine.trim().length() == 0));  
  57.         return inputLine;  
  58.     }  
  59.   
  60.     public Keygen(String _registrationName, String _company) {  
  61.         this.registrationName = null;  
  62.         this.company = null;  
  63.         this.registrationName = _registrationName;  
  64.         this.company = _company;  
  65.     }  
  66.   
  67.     private String getLicenseString() throws Exception {  
  68.         StringBuffer buffer = new StringBuffer();  
  69.         buffer.append(convertString(this.registrationName));  
  70.         buffer.append(convertString(this.company));  
  71.         buffer.append(formatter.format(new Date()));  
  72.         buffer.append("0");  
  73.         buffer.append("1000");  
  74.         buffer.append(convertString("Enterprise"));  
  75.         buffer.append(convertString("[Author, Author-Component, XML-Editor, XSLT-Debugger, SVN-Client, Saxon-SA, Diff-Srv, Diff-App, 1]"));  
  76.         buffer.append(convertString("18"));  
  77.         return buffer.toString();  
  78.     }  
  79.   
  80.     private String getLicenseSignature() throws Exception {  
  81.         Signature dsaSignature = Signature.getInstance("SHA1withDSA");  
  82.         dsaSignature.initSign(getPrivateKey());  
  83.         dsaSignature.update(getLicenseString().getBytes());  
  84.   
  85.         return Base64.encodeBase64String(dsaSignature.sign());  
  86.     }  
  87.   
  88.     private String getLicense() throws Exception {  
  89.         StringBuffer buffer = new StringBuffer();  
  90.         buffer.append("Registration_Name=" + this.registrationName).append('\n');  
  91.         buffer.append("Company=" + this.company).append('\n');  
  92.         buffer.append("Date=").append(formatter.format(new Date())).append('\n');  
  93.         buffer.append("Duration=-").append('\n');  
  94.         buffer.append("Number_of_Licenses=1000").append('\n');  
  95.         buffer.append("Category=Enterprise").append('\n');  
  96.         buffer.append("Component=Author,Author-Component,XML-Editor,XSLT-Debugger,SVN-Client,Saxon-SA,Diff-Srv,Diff-App,1").append('\n');  
  97.         buffer.append("Version=18").append('\n');  
  98.         buffer.append("SGN=" + getLicenseSignature());  
  99.         return buffer.toString();  
  100.     }  
  101.   
  102.     public static void main(String[] _args) {  
  103.         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));  
  104.         try {  
  105.             System.out.println("==================================================");  
  106.             System.out.println("=== <oXygen/>XML Editor v17.x license generator ===");  
  107.             System.out.println("==================================================");  
  108.             System.out.println();  
  109.             String registrationName = inputString(bufferedReader, "Registration name : ");  
  110.             String company = inputString(bufferedReader, "Company           : ");  
  111.             System.out.println();  
  112.             System.out.println("==================================================");  
  113.             System.out.println("License: ");  
  114.             System.out.println("==================================================");  
  115.             System.out.println();  
  116.             System.out.println(new Keygen(registrationName, company).getLicense());  
  117.             System.out.println();  
  118.             System.out.println("==================================================");  
  119.         } catch (Exception _exception) {  
  120.             _exception.printStackTrace();  
  121.         } finally {  
  122.             try {  
  123.                 bufferedReader.close();  
  124.             } catch (IOException localIOException1) {  
  125.             }  
  126.         }  
  127.     }  
  128. }  
oXygen XML Editor是一个多平台的XML编辑器(里诺下载站提供),XSLT / XQuery的调试器和分析器具有完整的Unicode支持。它提供了一个强大的代码洞察力,可以遵循DTD,RELAX NG或者XML架构,甚至可以从部分编辑过的文档学习的结构。XML和XSL文档可以容易地相关联的一个与另一个和变换结果可以被看作是文本或HTML。oXygen XML Editor提供了W3C XML模式的可视化模式编辑器和RELAX NG模式旨在简化架构文件的开发和理解。oXygen验证XML,XSL和XQuery,FO,XSD,RNG,RNC,NRL,DTD的Schematron,WSDL和CSS内容,报告与描述和行号信息错误,以及将它们标记在文档中时,验证您键入时启用。更多的文件可以被逻辑地组织在项目中。它配备了最新的Docbook DTD和样式表。   包括Apache的FO处理器,能够生成PDF和PostScript。其他FO处理器可以配置为插件。oXygen在调试模式进入,以显示来源和侧样式表文件侧,也显示效果和特殊的调试视图时提供了一个特殊的布局。调试和分析可以使用的Xalan,Xalan, Saxon 6 or Saxon 8转化引擎的最新版本来完成。动态呈现的输出,因为它是由变换过程完全与映射源和样式表产生的。一个完整的diff和合并的解决方案也提供oXygen。它提供了目录和文件比较,6档差异算法。oXygen通过包括Subversion客户端,使内容创作者之间更容易文档共享。svn客户端,您可以浏览库,检查变化,提交改变,更新你的工作副本并检查修订历史。oXygen支持导入数据库内容,微软Excel表和传统的文本数据文件到XML文档,也为从数据库表生成XML Schema的支持。
# -*- coding: utf-8 -*- import tkinter as tk from tkinter import messagebox, ttk import logging import numpy as np import matplotlib matplotlib.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure # 工业风格配色方案 INDUSTRIAL_THEME = { "background": "#2E2E2E", "foreground": "#E0E0E0", "accent1": "#FF4500", "accent2": "#1E90FF", "warning": "#FFD700", "machine_green": "#00FF00", "alarm_red": "#FF0000" } # 配置日志记录 logging.basicConfig( filename='steelmaking_errors.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s' ) # 设置中文字体 try: matplotlib.rcParams['font.family'] = 'Microsoft YaHei' except ValueError: matplotlib.rcParams['font.family'] = 'SimHei' matplotlib.rcParams['axes.unicode_minus'] = False class SteelAssistant: def __init__(self, master): self.master = master master.title("智能炼钢助手 v5.2") master.geometry("1400x1000") self.configure_style() # 初始化生产数据 self.gun_material_data = { 0.2: {"最高枪位": 1900, "最低枪位": 1300, "石灰石": 250, "铁矿石": 200}, 0.3: {"最高枪位": 2000, "最低枪位": 1400, "石灰石": 300, "铁矿石": 250}, 0.4: {"最高枪位": 2100, "最低枪位": 1500, "石灰石": 350, "铁矿石": 300}, 0.5: {"最高枪位": 2200, "最低枪位": 1600, "石灰石": 400, "铁矿石": 350}, 0.6: {"最高枪位": 2300, "最低枪位": 1700, "石灰石": 450, "铁矿石": 400}, 0.7: {"最高枪位": 2400, "最低枪位": 1800, "石灰石": 500, "铁矿石": 450}, 0.8: {"最高枪位": 2500, "最低枪位": 1900, "石灰石": 550, "铁矿石": 500} } self.first_charge_data = { 0.2: {"白云石": 1000, "石灰石": 2000, "镁球": 800, "铁矿石": 1500}, 0.3: {"白云石": 1000, "石灰石": 2000, "镁球": 800, "铁矿石": 1500}, 0.4: {"白云石": 1000, "石灰石": 2000, "镁球": 800, "铁矿石": 1500}, 0.5: {"白云石": 1000, "石灰石": 2500, "镁球": 800, "铁矿石": 1500}, 0.6: {"白云石": 1000, "石灰石": 2500, "镁球": 800, "铁矿石": 1500}, 0.7: {"白云石": 1000, "石灰石": 3000, "镁球": 800, "铁矿石": 1500}, 0.8: {"白云石": 1000, "石灰石": 3000, "镁球": 800, "铁矿石": 1500} } # 温度模拟参数 self.initial_temperature = 1335 self.temperature_increment = 50 self.simulation_steps = (1650 - self.initial_temperature) // self.temperature_increment + 1 self.temperatures = np.array([self.initial_temperature + i * self.temperature_increment for i in range(self.simulation_steps)]) # 图表参数 self.current_si = 0.5 self.plot_index = 0 self.limestone_data = [] self.iron_ore_data = [] self.chart_generated = False self.chart_completed = False self.end_point_reached = False try: self.create_widgets() self.setup_calculation_frames() self.create_input_chart() except Exception as e: logging.error(f"初始化失败: {str(e)}", exc_info=True) messagebox.showerror("启动失败", f"初始化错误: {str(e)}") master.destroy() def configure_style(self): """配置工业风格界面""" style = ttk.Style() style.theme_use('clam') style.configure('.', background=INDUSTRIAL_THEME["background"], foreground=INDUSTRIAL_THEME["foreground"], font=('微软雅黑', 9)) style.configure('TLabelFrame', background=INDUSTRIAL_THEME["background"], bordercolor=INDUSTRIAL_THEME["accent1"], relief='solid', labelmargins=5) style.configure('TLabelframe.Label', background=INDUSTRIAL_THEME["background"], foreground=INDUSTRIAL_THEME["accent2"], font=('微软雅黑', 10, 'bold')) style.configure('TEntry', fieldbackground='#454545', foreground=INDUSTRIAL_THEME["foreground"], insertcolor=INDUSTRIAL_THEME["foreground"]) style.configure('Alarm.TLabel', foreground=INDUSTRIAL_THEME["alarm_red"], font=('微软雅黑', 10, 'bold')) def create_widgets(self): """创建主界面组件""" main_frame = ttk.Frame(self.master, padding=10) main_frame.pack(fill=tk.BOTH, expand=True) # 输入参数面板 input_frame = ttk.LabelFrame(main_frame, text="▣ 工艺参数输入", padding=10) input_frame.pack(fill=tk.X, pady=5) parameters = [ ('目标碳含量 (%)', 'target_c'), ('终点碳含量 (%)', 'end_c'), ('Si 含量 (%)', 'si_content'), ('出钢量 (吨)', 'tapping_quantity'), ('首次取样C (%)', 'first_sample_c'), ('每秒降C量', 'per_second_dec'), ('终点氧 (ppm)', 'end_oxygen'), ('目标Si (%)', 'target_si'), ('终点Si (%)', 'end_si'), ('目标Mn (%)', 'target_mn'), ('终点Mn (%)', 'end_mn'), ('冷却水温度 (°C)', 'cooling_water') ] # 两列布局 left_frame = ttk.Frame(input_frame) right_frame = ttk.Frame(input_frame) left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5) self.entries = {} vcmd = (self.master.register(self.validate_input), '%P') for idx, (label, var_name) in enumerate(parameters): parent = left_frame if idx < 6 else right_frame row = ttk.Frame(parent) row.pack(fill=tk.X, pady=2) ttk.Label(row, text=label, width=15).pack(side=tk.LEFT) entry = ttk.Entry(row, validate='key', validatecommand=vcmd, width=10) entry.pack(side=tk.RIGHT) entry.bind("<KeyRelease>", self.update_calculations) self.entries[var_name] = entry def setup_calculation_frames(self): """创建计算结果显示区域""" main_frame = ttk.Frame(self.master) main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # 上部计算结果区域 top_frame = ttk.Frame(main_frame) top_frame.pack(fill=tk.BOTH, expand=True) self.blow_time_frame = ttk.LabelFrame(top_frame, text="▣ 动态吹炼参数", padding=10) self.blow_time_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) self.blow_time_result = ttk.Label(self.blow_time_frame, font=('Arial', 9)) self.blow_time_result.pack() self.alloy_frame = ttk.LabelFrame(top_frame, text="▣ 合金需求计算", padding=10) self.alloy_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) self.alloy_result = ttk.Label(self.alloy_frame, font=('Arial', 9)) self.alloy_result.pack() # 下部信息显示区域 bottom_frame = ttk.Frame(main_frame) bottom_frame.pack(fill=tk.BOTH, expand=True) self.equipment_frame = ttk.LabelFrame(bottom_frame, text="▣ 设备参数与温度影响", padding=10) self.equipment_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) self.equipment_result = tk.Text(self.equipment_frame, height=10, wrap=tk.WORD, bg='#3A3A3A', fg='#E0E0E0') self.equipment_scroll = ttk.Scrollbar(self.equipment_frame, orient="vertical", command=self.equipment_result.yview) self.equipment_result.configure(yscrollcommand=self.equipment_scroll.set) self.equipment_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.equipment_result.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.guide_frame = ttk.LabelFrame(bottom_frame, text="▣ 智能炼钢操作指南", padding=10) self.guide_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5) self.guide_text = tk.Text(self.guide_frame, height=10, wrap=tk.WORD, bg='#3A3A3A', fg='#E0E0E0') self.guide_scroll = ttk.Scrollbar(self.guide_frame, orient="vertical", command=self.guide_text.yview) self.guide_text.configure(yscrollcommand=self.guide_scroll.set) self.guide_scroll.pack(side=tk.RIGHT, fill=tk.Y) self.guide_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # 投入量曲线区域 self.input_frame = ttk.LabelFrame(main_frame, text="▣ 石灰和铁矿石投入量曲线", padding=10) self.input_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 工业状态指示灯 self.status_frame = ttk.LabelFrame(main_frame, text="▣ 系统状态监控", padding=10) self.status_frame.pack(fill=tk.X, pady=5) self.lance_status = ttk.Label(self.status_frame, text="氧枪状态: ", style='Alarm.TLabel') self.lance_status.pack(side=tk.LEFT, padx=5) self.water_status = ttk.Label(self.status_frame, text="冷却水状态: ", style='Alarm.TLabel') self.water_status.pack(side=tk.LEFT, padx=5) def create_input_chart(self): """创建优化后的投入量曲线图""" self.fig = Figure(figsize=(10, 6), dpi=100, facecolor=INDUSTRIAL_THEME["background"]) self.ax = self.fig.add_subplot(111) # 调整图表边距 self.fig.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.15) # 配置坐标轴样式 self.ax.set_facecolor(INDUSTRIAL_THEME["background"]) self.ax.tick_params(axis='both', colors=INDUSTRIAL_THEME["foreground"]) self.ax.spines['bottom'].set_color(INDUSTRIAL_THEME["foreground"]) self.ax.spines['left'].set_color(INDUSTRIAL_THEME["foreground"]) self.ax.spines['top'].set_visible(False) self.ax.spines['right'].set_visible(False) # 初始化空线条 self.limestone_line, = self.ax.plot([], [], label='石灰石投入量', marker='o', markersize=8, linewidth=3, color=INDUSTRIAL_THEME["accent2"], alpha=0.9) self.iron_ore_line, = self.ax.plot([], [], label='铁矿石投入量', marker='s', markersize=8, linewidth=3, color=INDUSTRIAL_THEME["accent1"], alpha=0.9) # 添加网格和标签 self.ax.grid(True, linestyle='--', alpha=0.3, color=INDUSTRIAL_THEME["foreground"]) self.ax.set_ylabel('投入量 (kg)', fontsize=12, color=INDUSTRIAL_THEME["foreground"]) # 动态文本标注(优化布局) self.current_temp_text = self.ax.text(0.02, 0.99, '', transform=self.ax.transAxes, color=INDUSTRIAL_THEME["foreground"], fontsize=10, verticalalignment='top') self.limestone_text = self.ax.text(0.02, 0.90, '', transform=self.ax.transAxes, color=INDUSTRIAL_THEME["accent2"], fontsize=9, verticalalignment='top') self.iron_ore_text = self.ax.text(0.02, 0.82, '', transform=self.ax.transAxes, color=INDUSTRIAL_THEME["accent1"], fontsize=9, verticalalignment='top') # 终点温度文本 self.end_temp_text = self.ax.text(0.02, 0.74, '', transform=self.ax.transAxes, color=INDUSTRIAL_THEME["foreground"], fontsize=10, verticalalignment='top', visible=False) # 初始化坐标范围 self.ax.set_xlim(self.initial_temperature - 50, 1700) self.ax.set_ylim(0, 3000) # 删除X轴刻度 self.ax.set_xticks([]) self.ax.set_xticklabels([]) # 添加图例(右下角) legend = self.ax.legend(loc='lower right', facecolor=INDUSTRIAL_THEME["background"], labelcolor=INDUSTRIAL_THEME["foreground"]) legend.get_frame().set_alpha(0.7) self.canvas = FigureCanvasTkAgg(self.fig, master=self.input_frame) self.canvas.draw() self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True) def generate_realistic_data(self, base_value): """生成更符合实际生产趋势的数据""" steps = len(self.temperatures) trend = np.linspace(base_value, base_value + 1200, steps) noise = np.random.normal(0, 50, steps) data = np.clip(trend + noise, base_value, None) max_allowed = 3000 data = np.clip(data, 0, max_allowed) return data def check_left_entries_filled(self): """检查左边的所有输入是否已经完成""" left_entries = ['target_c', 'end_c', 'si_content', 'tapping_quantity', 'first_sample_c', 'per_second_dec'] for entry in left_entries: if not self.entries[entry].get().strip(): return False return True def update_input_chart(self): """优化后的动态更新方法,1分钟更新一次""" if not self.chart_generated and self.entries['si_content'].get().strip(): try: current_data = self.gun_material_data.get(round(self.current_si, 1), {}) limestone_base = current_data.get("石灰石", 0) iron_ore_base = current_data.get("铁矿石", 0) self.limestone_data = self.generate_realistic_data(limestone_base) self.iron_ore_data = self.generate_realistic_data(iron_ore_base) max_value = max(max(self.limestone_data), max(self.iron_ore_data)) self.ax.set_ylim(0, max_value * 1.2) self.chart_generated = True self.chart_completed = False except Exception as e: logging.error(f"图表初始化错误: {str(e)}", exc_info=True) messagebox.showerror("初始化错误", f"图表初始化错误: {str(e)}") return if self.plot_index < len(self.temperatures) and not self.chart_completed: current_temp = self.temperatures[self.plot_index] current_limestone = self.limestone_data[self.plot_index] current_iron_ore = self.iron_ore_data[self.plot_index] # 更新线条数据 self.limestone_line.set_data( self.temperatures[:self.plot_index + 1], self.limestone_data[:self.plot_index + 1] ) self.iron_ore_line.set_data( self.temperatures[:self.plot_index + 1], self.iron_ore_data[:self.plot_index + 1] ) # 调整X轴范围 xlim_right = max(1650, current_temp + 50) self.ax.set_xlim(self.initial_temperature - 50, xlim_right) # 更新文本标注 self.current_temp_text.set_text(f'当前温度: {current_temp}°C') self.limestone_text.set_text(f'石灰石: {current_limestone:.0f} kg') self.iron_ore_text.set_text(f'铁矿石: {current_iron_ore:.0f} kg') # 动态调整文本位置,将当前温度文本标注位置进一步上移 if current_temp < 1400: self.current_temp_text.set_position((0.02, 0.99)) self.limestone_text.set_position((0.02, 0.90)) self.iron_ore_text.set_position((0.02, 0.82)) elif current_temp < 1500: self.current_temp_text.set_position((0.2, 0.99)) self.limestone_text.set_position((0.2, 0.90)) self.iron_ore_text.set_position((0.2, 0.82)) elif current_temp < 1600: self.current_temp_text.set_position((0.4, 0.99)) self.limestone_text.set_position((0.4, 0.90)) self.iron_ore_text.set_position((0.4, 0.82)) elif current_temp < 1650: self.current_temp_text.set_position((0.6, 0.99)) self.limestone_text.set_position((0.6, 0.90)) self.iron_ore_text.set_position((0.6, 0.82)) else: self.current_temp_text.set_position((0.8, 0.99)) self.limestone_text.set_position((0.8, 0.90)) self.iron_ore_text.set_position((0.8, 0.82)) self.canvas.draw() self.plot_index += 1 self.master.after(60000, self.update_input_chart) else: if not self.chart_completed: # 终点标注 self.ax.annotate('终点温度区', xy=(1650, self.limestone_data[-1]), xytext=(1600, self.limestone_data[-1] + 200), arrowprops=dict( facecolor=INDUSTRIAL_THEME["warning"], shrink=0.05 ), color=INDUSTRIAL_THEME["warning"], fontsize=10) # 显示终点温度文本 self.end_temp_text.set_text(f'终点温度: {self.temperatures[-1]}°C') self.end_temp_text.set_visible(True) self.canvas.draw() self.chart_completed = True self.end_point_reached = True def validate_input(self, P): """输入验证""" if P == '': return True try: float(P) return True except ValueError: return False def get_float(self, key): """安全获取浮点数值""" try: return float(self.entries[key].get()) except ValueError: return None def get_gun_data(self, si): """获取枪位配置""" return self.gun_material_data.get(round(si, 1), {"最高枪位": 2000, "最低枪位": 1400, "石灰石": 0, "铁矿石": 0}) def get_first_charge(self, si): """获取首批料参数""" return self.first_charge_data.get(round(si, 1), {"白云石": 1000, "石灰石": 2000, "镁球": 800, "铁矿石": 1500}) def update_calculations(self, event=None): """更新所有计算结果""" try: logging.debug("开始更新计算结果") si = self.get_float('si_content') if si is not None and si != self.current_si: self.current_si = round(si, 1) self.plot_index = 0 self.chart_generated = False self.chart_completed = False self.end_point_reached = False self.end_temp_text.set_visible(False) self.update_input_chart() self.update_blow_time() self.update_alloy() self.update_equipment() self.update_full_guide() self.update_status_indicators() logging.debug("计算结果更新完成") except Exception as e: logging.error(f"实时更新错误: {str(e)}", exc_info=True) messagebox.showerror("更新错误", f"实时更新错误: {str(e)}") def update_blow_time(self): """更新吹炼时间计算结果""" sample_c = self.get_float('first_sample_c') dec_rate = self.get_float('per_second_dec') if sample_c is not None and dec_rate is not None: if dec_rate == 0: result = "⚠️ 每秒降C量不能为零" else: time = (sample_c - 0.02) / dec_rate result = f"需吹炼时间: {time:.2f}秒" else: result = "需要:首次取样C含量、每秒降C量" self.blow_time_result.config(text=result) def update_alloy(self): """合金需求计算""" params = { 'tapping': self.get_float('tapping_quantity'), 'oxygen': self.get_float('end_oxygen'), 'target_si': self.get_float('target_si'), 'end_si': self.get_float('end_si'), 'target_mn': self.get_float('target_mn'), 'end_mn': self.get_float('end_mn'), 'target_c': self.get_float('target_c'), 'end_c': self.get_float('end_c') } results = [] # 铝锭计算 if params['oxygen'] is not None and params['tapping'] is not None: al = params['oxygen'] * 0.152 results.append(f"铝锭: {al:.1f}kg") # 硅铁计算 if all([params['target_si'] is not None, params['end_si'] is not None, params['tapping']]): si = ((params['target_si'] - params['end_si']) / 0.675) * params['tapping'] * 1000 results.append(f"硅铁: {si:.1f}kg") # 锰铁计算 if all([params['target_mn'], params['end_mn'], params['tapping']]): mn = ((params['target_mn'] - params['end_mn']) / 0.6175) * params['tapping'] * 1000 results.append(f"锰铁: {mn:.1f}kg") # 碳粉计算 if params['target_c'] and params['end_c']: carbon = (mn * 0.047) / 1000 c_powder = (params['target_c'] - params['end_c'] - carbon) / 0.0037 + 3 results.append(f"碳粉: {c_powder:.1f}包") self.alloy_result.config(text="\n".join(results) if results else "需要:出钢量、氧含量、Si/Mn含量") def update_equipment(self): """更新设备参数与温度影响信息""" si = self.get_float('si_content') cooling_water = self.get_float('cooling_water') if si is None: si = 0.3 gun_data = self.get_gun_data(si) first_charge = self.get_first_charge(si) # 设备状态分析 oxygen_lance_wear = 10.0 lance_status = "正常" if oxygen_lance_wear <= 15 else "需更换" # 温度影响计算 if '镁球' in first_charge: magnesium_cooling = -first_charge['镁球'] * 0.001 * 60 else: magnesium_cooling = 0 equipment_info = [ "=== 设备参数与温度影响 ===", f"初始枪位: {gun_data['最高枪位']}mm", f"氧枪磨损率: {oxygen_lance_wear}% ({lance_status})", f"冷却水温度: {cooling_water if cooling_water is not None else '未输入'}°C", "\n首批料配置:", f"白云石: {first_charge['白云石']}kg", f"石灰石: {first_charge['石灰石']}kg", f"镁球: {first_charge.get('镁球', 0)}kg", f"铁矿石: {first_charge['铁矿石']}kg", "\n温度影响分析:", f"枪位效应: +{(2500 - gun_data['最高枪位']) / 500 * 0.8:.2f}°C/min", f"铁矿石冷却: -{first_charge['铁矿石'] * 0.002 * 60:.1f}°C/min", f"石灰石冷却: -{first_charge['石灰石'] * 0.0015 * 60:.1f}°C/min", f"镁球冷却: {magnesium_cooling:.1f}°C/min", "\n设备建议:", f"冷却水{'过低' if cooling_water is not None and cooling_water < 20 else '过高' if cooling_water is not None and cooling_water > 40 else '正常'}", f"氧枪{'需要更换' if oxygen_lance_wear > 15 else '状态良好'}" ] self.equipment_result.delete(1.0, tk.END) self.equipment_result.insert(tk.END, "\n".join(equipment_info)) def update_full_guide(self): """更新智能炼钢操作指南""" si = self.get_float('si_content') sample_c = self.get_float('first_sample_c') end_c = self.get_float('end_c') gun_data = self.get_gun_data(si) if si else {} first_charge = self.get_first_charge(si) if si else {} guide = [ "=== 智能炼钢操作指南 ===", "\n【准备阶段】", "1. 确认钢种牌号及成分要求,检查氧枪、除尘系统状态", "2. 废钢配比:根据铁水成分调整废钢比例(建议15 - 25%)", "\n【原料加入】", "3. 废钢加入:摇炉至47度分3批加入,确保布料均匀", "4. 铁水注入:控制流速≤3分钟,保持炉内温度稳定", "\n【吹炼阶段】", f"5. 初始枪位:{gun_data.get('最高枪位', 'N/A')}mm", "6. 开吹参数:氧气流量65000Nm³/h,压力0.85MPa", f"7. 首次加料(20秒):白云石{first_charge.get('白云石', 'N/A')}kg + 石灰石{first_charge.get('石灰石', 'N/A')}kg", f"8. 二次加料(23秒):铁矿石{first_charge.get('铁矿石', 'N/A')}kg + 镁球{first_charge.get('镁球', 'N/A')}kg", "\n【过程控制】", f"9. 首次测温(9分45秒):C含量 {sample_c if sample_c else '未知'}%", "10. 根据火焰特征和声呐信号动态调整枪位", "\n【终点控制】", f"11. 终点碳命中:{end_c if end_c else '未知'}% ±0.015%", "12. 出钢温度:根据钢种要求控制在1620 - 1680℃", "\n【合金化】", "13. 采用‘高 - 低 - 高’合金加入模式:优先锰铁,后加硅铁,最后碳粉", "\n【后期处理】", "14. 溅渣护炉:使用镁碳渣调整炉渣粘度(MgO≥8%)", "15. 炉衬检查:使用激光测厚仪检测炉衬侵蚀情况" ] self.guide_text.delete(1.0, tk.END) self.guide_text.insert(tk.END, "\n".join(guide)) self.highlight_keywords() def highlight_keywords(self): """高亮关键工艺参数""" keywords = ["废钢配比", "氧气流量", "压力", "枪位", "温度", "摇炉", "布料", "镁球", "溅渣护炉", "激光测厚仪"] self.guide_text.tag_remove("highlight", "1.0", tk.END) for word in keywords: start = "1.0" while True: pos = self.guide_text.search(word, start, stopindex=tk.END) if not pos: break end = f"{pos}+{len(word)}c" self.guide_text.tag_add("highlight", pos, end) start = end self.guide_text.tag_config("highlight", foreground=INDUSTRIAL_THEME["accent1"]) def update_status_indicators(self): """更新工业状态指示灯""" cooling_water = self.get_float('cooling_water') oxygen_lance_wear = 10.0 # 氧枪状态 if oxygen_lance_wear > 15: self.lance_status.config(text="氧枪状态: 需要更换", foreground=INDUSTRIAL_THEME["alarm_red"]) else: self.lance_status.config(text="氧枪状态: 正常", foreground=INDUSTRIAL_THEME["machine_green"]) # 冷却水状态 if cooling_water is not None: if cooling_water < 20: self.water_status.config(text="冷却水状态: 过低", foreground=INDUSTRIAL_THEME["alarm_red"]) elif cooling_water > 40: self.water_status.config(text="冷却水状态: 过高", foreground=INDUSTRIAL_THEME["alarm_red"]) else: self.water_status.config(text="冷却水状态: 正常", foreground=INDUSTRIAL_THEME["machine_green"]) else: self.water_status.config(text="冷却水状态: 未输入", foreground=INDUSTRIAL_THEME["warning"]) if __name__ == "__main__": root = tk.Tk() app = SteelAssistant(root) root.mainloop() 在锰铁计算公式结果再加上100,然后优化一下界面
08-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值