Skip to content

Instantly share code, notes, and snippets.

@gregopet
Created January 9, 2014 08:50
Show Gist options
  • Save gregopet/8331291 to your computer and use it in GitHub Desktop.
Save gregopet/8331291 to your computer and use it in GitHub Desktop.
Helper class for the Coursera Cryptography course
/**
* Represents a byte sequence.
*/
class ByteSeq {
protected List sequence
/**
* Default constructor, creates an empty byte sequence.
*/
public ByteSeq() {
sequence = []
}
/**
* Constructs a hex string from the internal state.
*/
String getHex() {
sequence.collect{ Integer.toHexString(it).padLeft(2, "0") }.join()
}
/**
* Constructs a byte sequence from a String representation.
*/
void setHex(String hex) {
sequence = (hex.chars as List)
.collate(2,2,true)
.collect { Integer.parseInt(""+it[0]+it[1], 16) } as List
}
/**
* Sets the characters of this ASCII String as the source for the byte sequence.
*/
String getAscii() {
new String(sequence.toArray() as Byte[])
}
/**
* Gets the ASCII String encoded by this byte sequence.
*/
void setAscii(String ascii) {
sequence = ascii.bytes
}
/**
* Support index access to bytes.
*/
Byte getAt(int idx) {
sequence[idx]
}
void putAt(int idx, Number val) {
sequence[idx] = val
}
void putAt(int idx, String val) {
if (val.size() == 1) sequence[idx] = (int)val[0]
else throw new IllegalArgumentException("Cannot place more than 1 character into a single byte location!")
}
/**
* Bytewise XOR of two ByteSeq instances.
* @return A new ByteSeq instance.
*/
public ByteSeq xor(ByteSeq other) {
def xored = new ByteSeq()
int minSize = Math.min(sequence.size(), other.sequence.size())
for (int a = 0; a < minSize; a++) {
xored.sequence.push( (int)sequence[a] ^ (int)other.sequence[a] )
}
return xored
}
/**
* Bytewise AND of two ByteSeq instances.
* @return A new ByteSeq instance.
*/
public ByteSeq and(ByteSeq other) {
def xored = new ByteSeq()
int minSize = Math.min(sequence.size(), other.sequence.size())
for (int a = 0; a < minSize; a++) {
xored.sequence.push( (int)sequence[a] & (int)other.sequence[a] )
}
return xored
}
}
//generate sequence from ascii
def message = new ByteSeq(ascii:"We need more cake!")
println message.ascii //outputs: We need more cake!
println message.hex //outputs: 5765206e656564206d6f72652063616b6521
//generate sequence from a hex string
def hexSequence = new ByteSeq(hex:"3f203f")
println hexSequence.hex //outputs: 3f203f
println hexSequence.ascii //outputs: ? ?
//manipulate individual bytes via numbers, as ascii characters or hex strings
message[17] = 0x3f
println message.ascii //outputs: We need more cake?
message[17] = "."
println message.ascii //outputs: We need more cake.
//XOR
def transform = new ByteSeq(hex:"00000000000000000000000000100e0a1500")
println( (message ^ transform).ascii ) //outputs: We need more soap.
//AND
transform.hex = "00000000000000000000000000FFFFFFFF00"
println( (message & transform).ascii ) //outputs: cake
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment