import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.scene.control.*;
import javafx.geometry.*;
import javafx.stage.Stage;
public class CrcCalculator extends Application {
private TextField tfPurpose = new TextField();
private TextField tfSource = new TextField();
private ComboBox<String> cbLen = new ComboBox<>();
private TextField tfData = new TextField();
private TextField tfCmis = new TextField();
private Button btShow = new Button("查看");
private Button btCalculate = new Button("计算");
@Override
public void start(Stage primaryStage) throws Exception {
/*
* 输入和输出面板
*/
GridPane pane = new GridPane();
pane.setHgap(50);
pane.setVgap(50);
pane.setPadding(new Insets(15));
pane.add(new Label("目的地址:"), 0, 0);
pane.add(tfPurpose, 1, 0);
pane.add(new Label("源地址:"), 0, 1);
pane.add(tfSource, 1, 1);
cbLen.getItems().addAll("TEST0", "ARP0806", "IP0800");
cbLen.setValue("TEST0");
pane.add(new Label("长度字段:"), 0, 2);
pane.add(cbLen, 1, 2);
pane.add(new Label("数据字段:"), 0, 3);
pane.add(tfData, 1, 3);
pane.add(new Label("校检字段:"), 0, 4);
pane.add(tfCmis, 1, 4);
pane.add(btShow, 0, 5);
pane.add(btCalculate, 1, 5);
//将面板居中放置
pane.setAlignment(Pos.CENTER);
//光标右移
tfPurpose.setAlignment(Pos.BOTTOM_RIGHT);
tfSource.setAlignment(Pos.BOTTOM_RIGHT);
tfData.setAlignment(Pos.BOTTOM_RIGHT);
tfCmis.setAlignment(Pos.BOTTOM_RIGHT);
tfCmis.setEditable(false);
//按钮右边对齐
GridPane.setHalignment(btCalculate, HPos.RIGHT);
GridPane.setHalignment(cbLen, HPos.CENTER);
/*
* 业务逻辑层
*/
btCalculate.setOnAction(e->calculateCrc());
btShow.setOnAction(e-> showItem());
primaryStage.setScene(new Scene(pane));
primaryStage.setResizable(false);
primaryStage.show();
}
public Crc Deal() {
String sPurpose = tfPurpose.getText();
String sSource = tfSource.getText();
String sData = tfData.getText();
int[] purpose = new int[6];
int[] source = new int[6];
int[] len = new int[2];
int[] data = new int[200];
//处理长度字段
switch(cbLen.getValue()) {
case "TEST0": len[0] = 0;
len[0] = 0; break;
case "IP0800": len[0] = 8;
len[1] = 0; break;
case "ARP0806": len[0] = 8;
len[1] = 6; break;
default:
break;
}
// 处理目的地址
/*
* 若输入为空,则不做处理
* 若输入格式不对,则弹出提示框“目的地址格式错误”
* 若输入格式正确,则将16进制先转化为byte,再将byte类型转化为int类型
*/
if (sPurpose.equals("") || sPurpose.equals("0")) {
;
}
else if (sPurpose.length() != 17) {
Alert warning = new Alert(Alert.AlertType.WARNING, "目的地址格式错误");
warning.showAndWait();
}
else {
for (int i = 0 , j = 0; i < 17; i += 3, j++) {
purpose[j] = charToByte(sPurpose.charAt(i)) * 16
+ charToByte(sPurpose.charAt(i + 1));
}
}
//i+=3是为了跳过输入字符之前的分隔符,两个byte组成一个int
// 处理源地址
if (sSource.equals("") || sSource.equals("0")) {
;
}
else if (sSource.length() != 17) {
Alert warning = new Alert(Alert.AlertType.WARNING, "源地址格式错误");
warning.showAndWait();
}
else {
for (int i = 0 , j = 0; i < 17; i += 3, j++) {
source[j] = charToByte(sSource.charAt(i)) * 16
+ charToByte(sSource.charAt(i + 1));
}
}
// 处理数据部分
/*
* 两个字节的16进制byte,高位乘以16,低位乘以1可以转化为对应的int
*/
int dataLength = sData.length();
int numData = (dataLength + 1) / 3;
if (dataLength <= 137) {
for (int i = 0, j = 0; i < dataLength; i += 3, j++) {
data[46 - numData + j] = charToByte(sData.charAt(i)) * 16
+ charToByte(sData.charAt(i + 1));
}
data[46] = -1;
}
//数据不足46位的,前面部分填充0
/*int dataLength = sData.length();
int numData = (dataLength + 1) / 3;
if (dataLength <= 137) {
for (int i = 0, j = 0; i < dataLength; i += 3, j++) {
data[j] = charToByte(sData.charAt(i)) * 16
+ charToByte(sData.charAt(i + 1));
}
data[46] = -1;
}
//数据不足46位的,后面部分填充0*/
else {
int i, j ;
for (i = 0, j = 0; i < dataLength; i += 3, j++) {
data[j] = charToByte(sData.charAt(i)) * 16
+ charToByte(sData.charAt(i + 1));
}
data[j] = -1;
}
return new Crc(purpose, source, len, data);
}
public void calculateCrc() {
int arr = Deal().getCmis();
tfCmis.setText(arr + "");
}
public void showItem() {
String sPurpose = tfPurpose.getText();
String sSource = tfSource.getText();
String sData = tfData.getText();
String sCmis = tfCmis.getText();
int[] data = new int[200];
Stage secondStage = new Stage();
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(43));
gridPane.setHgap(20);
gridPane.setVgap(20);
gridPane.add(new Label("前导码:"), 0, 0);
Text tFront = new Text("0x55-55-55-55-55-55-55");
gridPane.add(tFront, 1, 0);
gridPane.add(new Label("帧前定位符:"), 0, 1);
Text tLocate = new Text("0xD5");
gridPane.add(tLocate, 1, 1);
gridPane.add(new Label("目的地址:"), 0, 2);
Text tPurpose;
if (sPurpose.equals("") || sPurpose.equals("0")) {
tPurpose = new Text("0x00-00-00-00-00-00");
}
else {
tPurpose = new Text("0x" + sPurpose);
}
gridPane.add(tPurpose, 1, 2);
gridPane.add(new Label("源地址:"), 0, 3);
Text tSource;
if (sSource.equals("") || sSource.equals("0")) {
tSource = new Text("0x00-00-00-00-00-00");
}
else {
tSource = new Text("0x" + sSource);
}
gridPane.add(tSource, 1, 3);
//展示长度字段
gridPane.add(new Label("长度字段:"), 0, 4);
String sLen = "";
switch(cbLen.getValue()) {
case "TEST0": sLen = "0x00-00";break;
case "IP0800": sLen = "0x08-00";break;
case "ARP0806": sLen = "0x08-06";break;
default:
break;
}
gridPane.add(new Text(sLen), 1, 4);
// 展示数据部分
int dataLength = sData.length();
int numData = (dataLength + 1) / 3;
if (dataLength <= 137) {
for (int i = 0, j = 0; i < dataLength; i += 3, j++) {
data[46 - numData + j] = charToByte(sData.charAt(i)) * 16
+ charToByte(sData.charAt(i + 1));
}
data[46] = -1;
}
else {
int i, j;
for ( i = 0, j = 0; i < dataLength; i += 3, j++) {
data[j] = charToByte(sData.charAt(i)) * 16
+ charToByte(sData.charAt(i + 1));
}
data[j] = -1;
}
String fData = "0x";
for (int i = 0; data[i] != -1; i++) {
fData += String.format("%X", data[i]);
if (data[i + 1] != -1) {
fData += "-";
}
}
gridPane.add(new Label("数据字段:"), 0, 5);
gridPane.add(new Text(fData), 1, 5);
//展示校检字段
gridPane.add(new Label("校检字段:"), 0, 6);
Text tCmis = null ;
if (sCmis.equals("")) {
tCmis = new Text("0x0-0-0-?");
}
else {
int cmis = Integer.parseInt(sCmis);
tCmis = new Text("0x0-0-0-" + String.format("%X", cmis));
}
gridPane.add(tCmis, 1, 6);
secondStage.setScene(new Scene(gridPane));
secondStage.setTitle("以太网帧详情");
secondStage.show();
}
public byte charToByte(char c) {
if ('A' <= c && c <= 'F')
return (byte)(c - 55);
return (byte)(c - 48);
}
public static void main(String[] args) {
launch(args);
}
}
/*50-7B-9D-DD-DB-F7 46-1C-A8-88-DA-8D 44-1C-A8-88-DA-8E*/