CMIS 310 Notes |
Local stuff |
CRC-12 | X12 + X11 + X3 + X2 + X + 1 | 1 1000 0000 1111 |
CRC-16 | X16 + X15 + X2 + 1 | 1 1000 0000 0000 0101 |
CRC-CCITT | X16 + X12 + X5 + 1 | 1 0001 0000 0010 0001 |
CRC-32 | X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X + 1 | 1 0000 0100 1100 0001 0001 1101 1011 0111 |
See Stallings, 6th edition, pages 206-207 for a more detailed
explanation of shift registers and calculating CRC's.
// example of a shift register, for appletviewer or over net
// as applet
// History:
// 10/23/1999 - created
// 10/27/1999 - added graphics
// 06/28/2019 - moved to swing + JFrame and JDK 8 features
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.event.*;
class ShiftRegisterSurface
extends JPanel
{
public static final long serialVersionUID = 123; // ND: junk
boolean [] poly, reg, msg;
int ind;
int regStart;
int width, height;
final int XSTEP = 8;
final int CIRCLERADIUS = 3;
final int YLINE=20, YREG=50;
public ShiftRegisterSurface (boolean [] p, boolean [] r, boolean [] m, int i) {
poly = p;
reg = r;
msg = m;
ind = i;
setPreferredSize (new Dimension (10, 150));
} // end normal constructor
public void paint (Graphics g) {
super.paint (g);
Dimension dim = new Dimension (getSize());
int x=2, y=YLINE;
String st;
setBackground (Color.yellow);
width = dim.width;
height = dim.height;
if (poly == null || reg == null) {
g.drawString ("Unitialized", x, y);
return;
} // end uninited
for (int i = poly.length - 1; i >= 0; i--) {
st = "0";
if (poly[i]) st = "1";
g.drawString (st, x, y);
x = x + XSTEP;
} // end for poly elements
x = width - 30 - msg.length * XSTEP;
regStart = x;
for (int i = 0; i < msg.length; i++) {
st = "0";
if (msg[i]) st = "1";
g.drawString (st, x, y);
x = x + XSTEP;
} // end for poly elements
drawRegisters (g);
} // end paint
public void markMessage (Graphics g) {
int x, y=YLINE;
g.setColor (Color.red);
g.drawRect (regStart + ind * XSTEP-1, y-15, XSTEP, 17);
g.setColor (Color.black);
} // end method markMessage
public void drawRegisters (Graphics g) {
int number = reg.length;
int x, xs, xs2, xcb, xd, xe, y, yl, ycb;
int cr=CIRCLERADIUS;
float step = (float) width / (float) (2 * number + 1);
String st1 = "1", st0 = "0";
xs = Math.round(step);
xs2 = Math.round (step/2.0f);
y = YREG;
x = Math.round (step * 0.5f);
xe = x + Math.round (step * (number * 2 - 0.5f));
xd = 3;
yl = y + 80;
g.drawLine (x+xs2, yl, xe, yl);
ycb = y - cr + 10;
g.drawLine (x+xs2, yl, x+xs2, y+20);
if (ind < msg.length) {
if (msg[ind]) g.drawString (st1, xe, y);
else g.drawString (st0, xe, y);
} // end if ind OK
markMessage (g);
for (int i = 0; i < number; i++) {
x = Math.round (step * (2*i + 0.5f) );
xcb = x+xs+xs2;
g.drawRect (x, y, xs, 20);
if (reg[number-i-1]) {
g.drawString (st1, x + xs2, y+15);
} // end if 1 in polynomial
else g.drawString (st0, x + xs2, y+15);
g.drawOval (xcb-cr,
ycb,
2*cr+1,
2*cr+1);
if (poly[number-i-1]) {
g.drawLine (xcb, yl, xcb, ycb+2*cr+1);
if (reg[number-1]) g.drawString (st1, xcb+xd, y+25);
else g.drawString (st0, xcb+xd, y+25);
} // end if poly = 1
g.drawLine (x+xs , ycb+cr, xcb-cr , ycb+cr);
if (i != number-1) g.drawLine (xcb+cr+1, ycb+cr, x+xs+xs, ycb+cr);
} // end for each element in register
} // end methoed drawRegisters
} // end class ShiftRegisterSurface
public class ShiftRegister
extends JFrame
{
public static final long serialVersionUID = 123; // ND: junk
ShiftRegisterSurface srs;
JPanel pan;
JTextField input;
JTextField polynomialStringInput;
JTextField crcStringInput;
JLabel inputLabel, polyLabel, crcLabel;
JTextField regField, infoField;
JButton stepButton, resetButton;
boolean[] register, message, poly, result;
int index;
// main:
public static void main (String [] args) {
new ShiftRegister ();
} // end main
// Methods
public boolean [] stringToBooleanArray (String st) {
return stringToBooleanArray (st, 0);
} // end method stringToBooleanArray (String)
public boolean [] stringToBooleanArray (String st, int len) {
boolean [] boolA = new boolean [st.length() + len];
for (int i = 0; i < st.length(); i++) {
if (st.charAt(i) == '0') boolA[i] = false;
else boolA[i] = true;
} // end for every character of string
for (int i = st.length(); i < st.length()+len; i++) {
boolA[i] = false; // append 0's
} // end for rest of string
return boolA;
} // end method stringToBooleanArray (String, int)
public ShiftRegister () {
pan = new JPanel(new GridLayout(5,2));
srs = new ShiftRegisterSurface(poly, register, message, 0);
srs.setSize (150,150);
srs.setBackground (Color.yellow);
srs.setVisible (true);
add (srs, BorderLayout.NORTH);
inputLabel = new JLabel ("Message: ");
inputLabel.setHorizontalAlignment (JLabel.RIGHT);
pan.add (inputLabel);
input = new JTextField (10);
pan.add (input);
polyLabel = new JLabel ("Polynomial: ");
polyLabel.setHorizontalAlignment (JLabel.RIGHT);
pan.add (polyLabel);
polynomialStringInput = new JTextField (10);
pan.add (polynomialStringInput);
crcLabel = new JLabel ("CRC String (Optional): ");
crcLabel.setHorizontalAlignment (JLabel.RIGHT);
pan.add (crcLabel);
crcStringInput = new JTextField (10);
pan.add (crcStringInput);
regField = new JTextField(20);
pan.add (regField);
infoField = new JTextField(20);
pan.add (infoField);
resetButton = new JButton ("Reset");
pan.add (resetButton);
stepButton = new JButton ("Step");
pan.add (stepButton);
add (pan, BorderLayout.SOUTH);
input.addActionListener (e -> reset());
polynomialStringInput.addActionListener (e -> reset());
crcStringInput.addActionListener (e -> reset());
resetButton.addActionListener (e -> reset());
stepButton.addActionListener (e -> stepRegister());
pack ();
setLocationRelativeTo (null);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
setVisible (true);
} // end constructor
public void reset () {
int padding;
String strPSI = polynomialStringInput.getText().trim();
String strCSI = crcStringInput.getText().trim();
String strMSI = input.getText().trim();
strPSI = strPSI.replaceAll (" ", "");
strCSI = strCSI.replaceAll (" ", "");
strMSI = strMSI.replaceAll (" ", "");
if (strMSI.length() == 0) return;
if (strPSI.length() == 0) return;
StringBuffer sb = new StringBuffer (strPSI);
sb.reverse();
poly = stringToBooleanArray (new String (sb));
padding = poly.length - 1;
if (strCSI.length() == padding) {
strMSI = strMSI + strCSI;
padding = 0;
} // end if crc right length
message = stringToBooleanArray (strMSI, padding);
index = 0;
srs.ind = index;
register = new boolean [poly.length - 1];
for (int i = 0; i < register.length; i++)
register [i] = false;
infoField.setText ("Reset");
regField.setText ("");
srs.poly = poly;
srs.reg = register;
srs.msg = message;
srs.repaint();
} // end method reset
public void stepRegister () {
boolean carry = register [register.length - 1];
if (index >= message.length) {
infoField.setText ("Carry: " + carry + " Index: " + index + " Done");
return;
} // end if message done
for (int i = register.length - 1; i > 0; i--) {
register [i] = register [i-1] ^ (carry & poly [i]);
} // end for 1 to n-1 register locations
register [0] = message [index] ^ carry;
index++;
srs.ind = index;
regField.setText ("Register: " + baToString (register));
infoField.setText ("Carry: " + carry + " Index: " + index);
srs.repaint();
} // end method stepRegister
public void printBooleanArray (boolean [] b) {
System.out.println (baToString (b));
} // end method printBooleanArray
public String baToString (boolean [] b) {
char [] sb = new char [b.length];
char trueChar = '1';
char falseChar = '0';
for (int i = 0; i < b.length; i++) {
if (b[i] == true) sb[b.length - i - 1] = trueChar;
else sb[b.length - i - 1] = falseChar;
} // end for every element in array
return new String (sb);
} // end method baToString
} // end class shiftRegister