# Secrets From The Future

I know I’ve covered this in some ancient blog post before, but I lost it, and the code that went with it.

# Message Digests

## Support

First, some support functions:

import collections

def rotl(x,amount,bits=32):
x&=2**bits-1
return ((x<<amount)|(x>>(bits-amount)))&(2**bits-1)

def rotr(x,amount,bits=32):
x&=2**bits-1
return ((x>>amount)|(x<<(bits-amount)))&(2**bits-1)

m=message[:]
m.extend(tagbytes if isinstance(tagbytes,collections.Iterable) else [tagbytes])
return m

def hexdigest(digest,length=32,endianness='little'):
raw=digest.to_bytes(16,endianness)
return ('{:0'+str(length)+'x}').format(int.from_bytes(raw,'big'))

The functions rotl  and rotr  are rotate left and rotate right, respectively, taking in x  (the value to rotate), amount  (the number of bits to rotate), and bits  (the total number of bits in the result).

The function pad  is important. Many, if not most, encryption and hashing functions require a multiple of a known number of bits or bytes in the input to operate properly. So this pads the input message such that its length is congruent to length  mod mod .

Starting with the math, if we want, say, $$x \equiv 448 \pmod {512}$$, $$x$$ can be 448, or it can be 960, or 1472, 1984, etc.

So if we have a message, say the alphabet (abcdefghijklmnopqrstuvwxyz, 26 letters) and we need the length to be congruent to $$0 \pmod {16}$$, we need to pad it with 6 extra characters. In our case, each character in the message is represented to the computer by a single byte, so we’ll need to add six bytes. Exactly how the padding is applied can vary from algorithm to algorithm.

The parameters tagbytes  and padbyte  are typical, though my names are possibly unique. For this function, tagbytes  (one or more bytes) will be “tagged” to the end of the message first, and any padbyte  will be used to pad out the message following the tagbytes. A typical scenario: the algorithm requires I add a ‘1’ (bit) to the end of the message, and pad the remainder to a length in bits congruent to $$448 \pmod {512}$$. So I pass tagbytes=0x80  and padbyte=0x00  (the default values here) to perform that operation. It is rather unlikely I’ll have a message whose length in bits is not a multiple of 8, so I don’t consider that case. Here, anyway.

For all digests, there’s this general procedure

2. Process message
3. Return digest

## MD2

RFC 1319 (and the extremely important errata) covers the MD2 message digest function. But how would one go about implementing this in Python?

Following our general procedure:

We pad this message so its length in bytes is congruent to $$0 \pmod {16}$$, by adding i bytes of value i to the message. But padding of some kind must be added, so if the message length is already congruent to $$0 \pmod {16}$$, add 16 bytes of value 16 to the message.
Next we add a 16-byte checksum to the end of the message. I won’t go into details here as it’s in my code, but this is where the errata from the RFC is important!
2. Process message
Prime the buffer, then run it through 18 rounds of 48 exclusive ors with the S-table (which, in this case, is a hexidecimal representation of π).
3. Return digest
import support
import math

#md2
s_table=[0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14]

#add padding of i bytes of i such that message length is congruent to 0 mod 16
m=bytearray(message,encoding)
l=len(m)
tagbyte=(16-len(m))%16
tagbyte=(tagbyte if tagbyte>0 else 16)
#append checksum
checksum=bytearray(16)
L=0
for i in range(len(m)//16):
for j in range(16):
c=m[i*16+j]
checksum[j]=checksum[j]^s_table[c^L]
L=checksum[j]
m.extend(checksum)
return m

def md2(message,encoding='utf-8'):
d=process(m)
return d

def process(message):
X=bytearray(48) #buffer
for i in range(len(message)//16):
for j in range(16):
X[16+j]=message[i*16+j]
X[32+j]=X[16+j]^X[j]
t=0
for j in range(18):
for k in range(48):
t=X[k]=(X[k]^s_table[t])
t=((t+j)%256)
return sum(x<<(8*i) for i,x in enumerate(X[:16]))

if __name__=='__main__':
print('testing MD2:')
test_vectors=(('','8350e5a3e24c153df2275c9f80692773'),
('a','32ec01ec4a6dac72c0ab96fb34c0b5d1'),
('abc','da853b0d3f88d99b30283a69e6ded6bb'),
('message digest','ab4f496bfb2a530b219ff33031fe06b0'),
('abcdefghijklmnopqrstuvwxyz','4e8ddff3650292ab5a4108c3aa47940b'),
('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789','da33def2a42df13975352846c30338cd'),
('12345678901234567890123456789012345678901234567890123456789012345678901234567890','d5976f79d83d3a0dc9806c3c66f3efd8'))
for t,r in test_vectors:
d=support.hexdigest(md2(t))
print('digest \'{}\': {}, {}'.format(t,d,'passed' if d==r else 'failed'))


Now, the part that nobody ever shows, which frustrates me when debugging, is the step-by-step, what’s going on inside. That’s the main reason I’m adding to the noise. I’ll run three messages: the empty string, the letter “a”, and, for this one, the alphabet “abcdefghijklmnopqrstuvwxyz”. That should cover all relevant cases

### Null String Step-By-Step

Our message begins as m=b”. Such an innocent looking piece of code.

First, the padding. i bytes of value i such that message length is congruent to $$0 \pmod {16}$$. It already is, but we have to add something to the end, so 16 bytes of value 16 it is. We wind up with

m=b'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'

at line 28. Next part of the padding is the checksum. The outer “for” loop is once for every 16 bytes of the message, and since this message is only 16 bytes long, it’s only run once, and i=0. The inner loop is run for each byte. Starting with an empty checksum bytearray (all bytes in the checksum initialized to 0) and L=0, our first pass gives

c=m[i*16+j]=m[0+0]=m[0]=b'\x10'=16
checksum[j]=checksum[j]^s_table[c^L]=0^s_table[16^0]=0^s_table[16]=0x62=98
L=checksum[j]=0x62=98


For this special case, c will always be 16. But L changes for every iteration (and I’ll only show checksum, because L becomes equal to that value each time around), so

checksum[0]^s_table[16^0]=0^s_table[16]=0x62=98
checksum[1]^s_table[16^98]=0^s_table[114]=0x38=56
checksum[2]^s_table[16^56]=0^s_table[40]=0x67=103
checksum[3]^s_table[16^103]=0^s_table[119]=0xB6=182
checksum[4]^s_table[16^182]=0^s_table[166]=0xAF=175
checksum[5]^s_table[16^175]=0^s_table[191]=0x52=82
checksum[6]^s_table[16^82]=0^s_table[66]=0x79=121
checksum[7]^s_table[16^121]=0^s_table[105]=0x5E=94
checksum[8]^s_table[16^94]=0^s_table[78]=0x5F=95
checksum[9]^s_table[16^95]=0^s_table[79]=0x21=33
checksum[10]^s_table[16^33]=0^s_table[49]=0x4E=78
checksum[11]^s_table[16^78]=0^s_table[94]=0x97=151
checksum[12]^s_table[16^151]=0^s_table[135]=0x20=32
checksum[13]^s_table[16^32]=0^s_table[48]=0xBE=190
checksum[14]^s_table[16^190]=0^s_table[174]=0xEA=234
checksum[15]^s_table[16^234]=0^s_table[250]=0x8D=141

Tack those on to the end and we get

m=b'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10b8g\xb6\xafRy^_!N\x97 \xbe\xea\x8d'

At the beginning, the buffer is (in this case) simply composed of the following:

X=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'

Since our message is now 32 bytes long, we need to do two rounds of 18 rounds of 48. Originally I was going to put it all directly in the post, but that’s way too much. Instead, here’s a text file:

MD2 Null String debug text

### Short Input Step-By-Step

In this context, a “short” input is one that is longer than 0 bytes but shorter than the padding requirement (for MD2, between 0 and 15 bytes). The input used here is ‘a’. I’ll skip the details and instead provide the debug text file.

MD2 short input debug text

### Long Input Step-By-Step

In this context, a “long” input is one that is longer than the padding requirement (for MD2, greater than 16 bytes). The input used here is ‘abcdefghijklmnopqrstuvwxyz’. This, in particular, requires two rounds of the checksum, which is why the errata is so important. I’ll skip the remainder of the details and instead provide the debug text file.

MD2 long input debug text

## MD5

This one’s actually still vaguely relevant today, despite the fact that collision attacks are easy to come by.

RFC 1321 covers the MD5 message digest function.

Following our general procedure:

We pad this message so its length in bits is congruent to $$448 \pmod {512}$$, by adding first a ‘1’ bit, then ‘0’ bits until the length is appropriate. Since a ‘1’ is always added, there is always padding of some sort.
Next we add the length of the original message in bits as a 64-bit number in little-endian byte order.
2. Process message
3. Return digest
import support
import math

#md5
rotate_amounts=[ 7,12,17,22, 7,12,17,22, 7,12,17,22, 7,12,17,22,
5, 9,14,20, 5, 9,14,20, 5, 9,14,20, 5, 9,14,20,
4,11,16,23, 4,11,16,23, 4,11,16,23, 4,11,16,23,
6,10,15,21, 6,10,15,21, 6,10,15,21, 6,10,15,21]
constants=[int(abs(math.sin(i+1))*2**32) for i in range(64)]
functions=16*[lambda b,c,d:(b&c)|(~b&d)]+\
16*[lambda b,c,d:(d&b)|(~d&c)]+\
16*[lambda b,c,d:b^c^d]+\
16*[lambda b,c,d:c^(b|~d)]
index_functions=16*[lambda i:i]+\
16*[lambda i:(5*i+1)%16]+\
16*[lambda i:(3*i+5)%16]+\
16*[lambda i:(7*i)%16]

m=bytearray(message,encoding)
l=(8*len(m))%(2**64)
m+=l.to_bytes(8,'little')
return m

def md5(message,encoding='utf-8'):
d=process(m)
return d

def process(message):
hash_pieces=init_values[:]
for chunk_offset in range(0,len(message),64):
a,b,c,d=hash_pieces
chunk=message[chunk_offset:chunk_offset+64]
for i in range(64):
f=functions[i](b,c,d)
g=index_functions[i](i)
to_rotate=a+f+constants[i]+int.from_bytes(chunk[4*g:4*g+4],'little')
new_b=(b+support.rotl(to_rotate,rotate_amounts[i]))&0xffffffff
a,b,c,d=d,new_b,b,c
for i,val in enumerate([a,b,c,d]):
hash_pieces[i]+=val
hash_pieces[i]&=0xffffffff
return sum(x<<(32*i) for i,x in enumerate(hash_pieces))

if __name__=='__main__':
print('testing MD5:')
test_vectors=(('','d41d8cd98f00b204e9800998ecf8427e'),
('a','0cc175b9c0f1b6a831c399e269772661'),
('abc','900150983cd24fb0d6963f7d28e17f72'),
('message digest','f96b697d7cb7938d525a2f31aaf161d0'),
('abcdefghijklmnopqrstuvwxyz','c3fcd3d76192e4007dfb496cca67e13b'),
('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789','d174ab98d277d9f5a5611c2c9f419d9f'),
('12345678901234567890123456789012345678901234567890123456789012345678901234567890','57edf4a22be3c955ac49da2e2107b67a'))
for t,r in test_vectors:
d=support.hexdigest(md5(t))
print('digest \'{}\': {}, {}'.format(t,d,'passed' if d==r else 'failed'))

# Color Me Once

I have determined that I hate Magick++. I already mentioned something to that effect here, and I’m frustrated enough to consider writing my own image interface, even if it’s RAW or BMP, at least I’d get an image!

# Nobody Knows

For roughly two years I’ve been silent on religion. For roughly two years I’ve “tiptoed through the tithers” and avoided basically any discussion of what I believe or where I go to church. I live in Kansas, you see, and if you’re not a bible-thumping, gun-toting, pro-life, card-carrying Republican, people tend to look at you funny. I’m none of those things. The big secret, though, is that I am not a Christian of any stripe. I’ve only told a few before today. But I’m tired of hiding this aspect of myself, pretending I’m “just like everyone else”, dodging the subject when friends and family ask me about my spiritual life.

I am an atheist.

I’ll probably expound on this at a later date [update: story here], but I want it out there so I don’t feel obligated to maintain the noble lie—it’s a lot of work, and lies are so much harder than the truth.

# Looking for Satellites

So my current CD/DVD/Blu-Ray rack is overfull, and I now that my collection is combined with my wife’s, there’s…rather a lot of extra media that needs to be placed on a new rack, or racks. So I’ve designed a new one based on the old one. My old rack wasn’t so much designed as I just drilled holes in what looked like appropriate places (using paper templates to stand in for DVDs and CDs) and it does an excellent job. I decided to be a bit more scientific about the second one, and while I’m not quite done, I decided I’d provide an iso image and the sketchup model in case anyone wants to build one like mine. I bought two 1″×8″×8′ pine boards and eighteen 1/2″×48″ dowels (that’s 1/2″ diameter, not 48″ diameter :P) I had them cut the 8′ boards in half both so they’d fit in my car and because that’s the intended height. I’m building two, so if you want just one identical to the drawing, just one 1″×8″×8′ will be plenty—though if you want something that’s simply twice as wide, I recommend using three 1″×8″×4′, with one board in the center to support the weight. This drawing is like my old one in that there’s two shelves for DVDs/Blu-Rays and four for CDs. Though I’ve provided (and illustrated) CDs on those rows, and a DVD and Blu-Ray on those, I realized that my largest box set is 7 3/4″ tall, more than the 190mm typical, and since I wanted a gap between rows, I made sure to account for it.

Anyway, the details!

The original (taken from my tall perspective—the sofa is in the way of taking a better picture):

(and the wood for the new one on the left)

The design:

SketchUp model

# Last to Know

So lambda functions are totally possible in C++!

I’m going back to the old standby of the Mandelbrot set generator as I’m re-teaching myself template classes, and found this cool feature of C++11. So instead of writing

complex mandel(complex z,complex c) {
return z*z+c;
}

(which, admittedly, is already pretty terse, and could be moved to a single line), there’s another way to do this!

auto mandel = [](complex z,complex c)->complex{return z*z+c;};

This would be called just like the above function.

Oh, and the auto  keyword, which automagically figures out what the data type is supposed to be! Not sure if this is done at runtime or compile time, though, so until I know I’ll be careful when using it.

I made fairly frequent use of lambdas in Python already (e.g. lambda mandel=z*z+c for the same thing), and I’m not yet sure how well this will serve me in the future, but it’s nifty nonetheless.

On a slightly related note, Magick++ is not (in my opinion) programmer friendly. I’d like an interface to which I can pass a size, a vector full of RGB(A) tuples, and a filename, and I get a nice, properly formatted, pretty picture. The other thing that I would like would be to not have to pass in the following compiler flags:

g++ file.cpp -fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/usr/include/ImageMagick-6
-fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -fopenmp -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/usr/include/ImageMagick-6
-lMagick++-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lpng16 -lm -lz -ljpeg -lgs -lpng16 -lautotrace -lpng -lz -lm -lMagickCore-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lm -lz -ljpeg -lgs -lautotrace -lpng -lz -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lMagickCore-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lm -lz -ljpeg -lgs -lautotrace -lpng -lz -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lpng16 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lpng16 -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lMagickWand-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lpng16 -lm -lz -ljpeg -lgs -lpng16 -lautotrace -lpng -lz -lm -lMagickCore-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lm -lz -ljpeg -lgs -lautotrace -lpng -lz -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lMagickCore-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lm -lz -ljpeg -lgs -lautotrace -lpng -lz -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lpng16 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lpng16 -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lMagickCore-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lpng16 -lm -lz -ljpeg -lgs -lpng16 -lautotrace -lpng -lz -lm -lMagickCore-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lm -lz -ljpeg -lgs -lautotrace -lpng -lz -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lMagickCore-6.Q16 -ljbig -llcms2 -ltiff -lfreetype -lbz2 -lz -lm -lz -ljpeg -lgs -lautotrace -lpng -lz -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm -lming -lm -lpstoedit -lpng -lz -lstdc++ -ldl -lfftw3 -lfpx -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lwebp -lXext -lXt -lSM -lICE -lX11 -llzma -lbz2 -lpangocairo-1.0 -lcairo -lz -lGL -lpixman-1 -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lpangoft2-1.0 -lharfbuzz -lpango-1.0 -lm -lgmodule-2.0 -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lrsvg-2 -lm -lgio-2.0 -lz -lgdk_pixbuf-2.0 -lm -lgmodule-2.0 -lpng16 -lm -lz -lcairo -lz -lGL -lgobject-2.0 -lffi -lglib-2.0 -lintl -lpcre -lintl -liconv -lpcre -lpixman-1 -lfontconfig -lexpat -lfreetype -lbz2 -lz -lpng16 -lm -lz -lexpat -lfreetype -lbz2 -lz -lEGL -lm -lpthread -lGL -lm -lpthread -lXdamage -lXfixes -lX11-xcb -lxcb-glx -lpng16 -lm -lz -lxcb-shm -lxcb-render -lXrender -lXext -lX11 -lxcb -lXau -lXdmcp -lxml2 -lz -lgdi32 -lm -lgomp -lm

That’s more than a little ridiculous. Fortunately, a shortcut is provided, and (if pkg-config  is installed), I can run instead

g++ file.cpp Magick++-config --cppflags --cxxflags --ldflags --libs

The following function theoretically should produce a nice, white image (when appropriate libraries are included and linked):

void plot(window<int> &scr,const char *fname) {
InitializeMagick(NULL);
unsigned int width,height;
width=scr.width();
height=scr.height();
Image output_image(Geometry(width,height),Color(MaxRGB,MaxRGB,MaxRGB,0));
output_image.write(fname);
}

The window template function is to make it easy to pass around a viewport or range of values. There’s an x_min , x_max , y_min , and y_max  in there, and the member functions width and height simply return the differences.