COS 126 Linear-Feedback Shift Register |
Programming Assignment Checklist Assignment Page |
Preparation |
What are the goals of this assignment? To introduce you to object-oriented programming and to re-reinforce the message of Lecture 0.
Where can I review the concepts involved? Review Lecture 0 to reacquaint yourself with the basic ideas behind LFSRs. Read Sections 3.1 and 3.2 of the textbook to learn the basics of object-oriented programming and how to use Color and Picture data types.
Frequently Asked Questions (LFSR) |
Does the API that I define for LFSR
need to be exactly the same as the one prescribed?
Yes, we will be testing the methods in the API directly.
If your method has a different signature or does not behave as specified
you will lose a substantial number of points.
Producing undocumented side effects (such as printing to
standard output in any of the constructor or instance methods)
is also an API violation.
You may not add public methods to the API; however, you may add private methods
(which are accessible only in the class in which they are declared).
How should I represent the LFSR? There are several possible approaches. For example, you can use an int[] array of length n + 1, each entry of which is either 0 or 1, with entry i corresponding to bit i for each i from 1 to n. If you follow this approach, the constructor amounts to creating the array and converting the char values in the string to int values for the array (and initializing your other instance variables). However, you are allowed to use any efficient representation that you like.
How do I create an instance variable that is an array if I don't know its length at compile time? Declare it as an instance variable, but initialize it in constructor (where you will know its length). For example, see Program 3.2.3 in the textbook.
What extra comments should I include when writing object-oriented programs? You must comment the purpose of every method, using the names of the argument variables in your description. Additionally, you must comment the purpose of each instance variable.
In the initial register, seed.charAt(0) is the leftmost bit. However, in both Lecture 0D and the assignment specification, bit 1 is the rightmost bit. Do I have to arrange the bits in my register array that way? Traditionally, strings are indexed from left to right, while binary numbers are indexed from right to left. You are welcome to use either approach here—just be careful to do it correctly and consistently.
How do I convert the char values in the String argument to int values for the array? The characters zero and one are represented by the char literals '0' and '1'. The char data type is a Java primitive type, so you can compare two of them with if (c == '0').
Why am I getting 48s and 49s when I print out values for debugging? Internally, characters are represented as integers. The code for '0' is 48, and the code for '1' is 49. (Read about ASCII or Unicode for more information.) When you perform arithmetic operations on values of type char, they are promoted to type int. So, the expressions '0' + 1 and '1' ^ '1' ^ '1' both evaluate to the value 49 of type int. We recommend converting from the characters '0' and '1' to the integers 0 and 1, so that you don't have to deal with such type conversion anomalies.
In toString(), I loop the right number of times, but the returned String looks too short. What can cause this? This can be the reverse of the problem above. If you take the integer 0 or 1 and cast it to a char, it is a special control character that may appear blank when printed.
My generate() method is producing 19 for the binary number 11001. What am I doing wrong? You are calculating the bits in reverse order. 19 is the decimal value of the binary number 10011.
My generate() works with the 11-bit seed and the tap at position 9, but when I try generate()with the 20-bit seed and the tap at position 17, I get a different answer from the one shown in the example. What am I doing wrong? Make sure you are not hardwiring 9 or 11 in your code. The LFSR constructor arguments must set the size of the register and the tap position.
The toString() is not explicitly called in the test client code, but it still gets called. How does this work?
LFSR lfsr = new LFSR("01101000010", 9); StdOut.println(lfsr);
Every object in Java has a toString() method, which is automatically called by StdOut.println().
I get an ArrayOutOfBounds or NullPointerException error. What could cause this? Do your constructors initialize all of the instance variables (e.g., n, reg, and tapPosition)? Did you allocate memory for your array with new? Did you inadvertently re-declare int n or int[] reg in a method or constructor, thereby hiding the instance variable with the same name?
How do I perform the exclusive or (xor) operation in Java? Use the ^ operator.
Frequently Asked Questions (PhotoMagic) |
Does the API that I define for PhotoMagic
need to be exactly the same as the one prescribed?
Yes, we will be testing the methods in the API directly.
If your method has a different signature or does not behave as specified,
you will lose a substantial number of points.
Producing undocumented side effects (such as printing to
standard output or mutating the Picture argument to transform())
is also an API violation.
You may not add public methods to the API; however, you may add private methods
(which are accessible only in the class in which they are declared).
Why must I create a new Picture object in transform(), instead of mutating the one passed in as argument? The API does not specify this is an allowable side effect, so it is not permitted. In practice, a client might be very annoyed if an object they passed to a method was mutated with proper documentation.
Why are we using the PNG format instead of JPEG? PNG is a lossless format that preserves the precise bits in the colors.
How do I read and process PNG files?
Use the Color
and Picture
data types
described in Section 3.1 of the textbook.
Review Program 3.1.3 (Luminance.java)
for using the Color data type; review
either Program 3.1.4 (Grayscale.java)
or ColorSeparation.java
for using the Picture data type.
Sometimes my encrypted picture looks like a shadowy version of the original. How do I pick a good tap number? Here are suggested tap numbers for maximizing the cycle of different size linear-feedback shift registers: 5-bit (tap 3), 6-bit (tap 5), 9-bit (tap 5), 10-bit (tap 7), 11-bit (tap 9), 20-bit (tap 17), 30-bit (tap 23), 36-bit (tap 25), 48-bit (tap 43), 60 bit (tap 59), 100 bit (tap 63), and 150 bit (tap 97).
How can I save an Picture that is displayed in a window? Select File -> Save -> filename.png from the menu in the window where the image is displayed, where filename is whatever name you want to give the image.
What is a java.awt.HeadlessException and how did I cause it? The assignment specifies that you should call show() only once, in PhotoMagic.main(). Calling it in other places can give this error.
|
The Color data type is built into Java in the "Abstract Window Toolkit" package.
import java.awt.Color;
// constructor arguments are red, green, and blue components Color princetonOrange = new Color(245, 128, 37);
|
The Picture data type was created for this course.
If it's working (and you have an Internet connection), you will see an image of a baboon displayed in a window and the text output 298-by-298 at the command line.% java-introcs Picture http://introcs.cs.princeton.edu/java/31datatype/baboon.png
// create a picture from a URL (Internet connection required) Picture picture1 = new Picture("http://introcs.cs.princeton.edu/java/31datatype/baboon.png"); // create a picture from a file (baboon.png must be in working directory) Picture picture2 = new Picture("baboon.png"); // display pictures in separate windows picture1.show(); picture2.show();
Testing |
Be sure to thoroughly test each piece of your code as you write it. We offer some suggestions in the assignment specification. You should also test your data type with other parameters.
It outputs:LFSR lfsr20 = new LFSR("01101000010100010000", 17); StdOut.println(lfsr20); for (int i = 0; i < 10; i++) { int r = lfsr20.generate(8); StdOut.println(lfsr20 + " " + r); }
01101000010100010000 01010001000000101010 42 00000010101011011001 217 10101101100100010111 23 10010001011111000001 193 01111100000100011010 26 00010001101010011100 156 10101001110010011100 156 11001001110011100111 231 11001110011110000111 135 01111000011110111101 189
% java-introcs PhotoMagic pipe.png 01101000010100010000 17
Before: 135 98 80 After: 173 187 71 Before: 141 104 86 After: 76 114 202 Before: 146 109 91 After: 14 138 220 Before: 146 109 91 After: 47 214 254
PhotoMagic. Here are a few sample executions of PhotoMagic.java along with the desired output.
% java-introcs PhotoMagic pipe.png 01101000010100010000 17 % java-introcs PhotoMagic Xpipe.png 01101000010100010000 17 % java-introcs PhotoMagic Xpipe-gray.png 10010111101011101111 17 % java-introcs PhotoMagic Xbaboon-gray.png 01101000010100010000 17 % java-introcs PhotoMagic Xbaboon-red.png 01101000010100010000 17 % java-introcs PhotoMagic Xbaboon-green.png 01101000010100010000 17 % java-introcs PhotoMagic Xbaboon-blue.png 01101000010100010000 17 % java-introcs PhotoMagic Xshield.png 010101010101010101010101010101 23 % java-introcs PhotoMagic Xscarpet-cookies.png 01101000010100010000 17 [ picture of something delicious ] % java-introcs PhotoMagic Xjava.png 001110001111000100001101010010000100010010000000001100000100 59 [ picture of something you could drink with cookies ]
Possible Progress Steps |
These are purely suggestions for how you might make progress. You do not have to follow these steps.
int[]
array
and the following instance variables:
private int n; // number of bits in the LFSR private int[] reg; // reg[i] = ith bit of LFSR, reg[1] is rightmost bit private int tapPosition; // tap position
Test the constructor. In the LFSR main method, instantiate several different LFSR objects, varying the values for the seed and tap position.
Test the length method. In the LFSR main method, invoke the length method on the LFSR objects (from step 4) and print the resulting value. Are your results correct?
Test the bitAt method. In the LFSR main method, invoke the bitAt method using different values for the argument i on the LFSR objects (from step 4) and print the resulting value. Are your results correct? Is the value of your tap correct?
Test the toString method. In the LFSR main method, invoke StdOut.println on the LFSR objects you instantiated (from step 4). Are your results correct?
Test the step method. In the LFSR main method, invoke the step method on the the LFSR objects you instantiated (from step 4). Are your results correct? You should also use the test code provided in the assignment.
Test the generate method. Use the test code provided in the assignment.
|