The Marble Faun
by Nathaniel Hawthorne
Conclusion
Additional Information
- Year Published: 1860
- Language: English
- Country of Origin: United States of America
- Source: Hawthorne, N. (1860). The Marble Faun. Boston: Ticknor and Fields.
-
Readability:
- Flesch–Kincaid Level: 11.5
- Word Count: 1,462
- Genre: Gothic
- Keywords: 19th century literature, american literature, nathaniel hawthorne, the marble faun
- ✎ Cite This
Downloads
There comes to the author, from many readers of the foregoing pages, a demand for further elucidations respecting the mysteries of the story.
He reluctantly avails himself of the opportunity afforded by a new edition, to explain such incidents and passages as may have been left too much in the dark; reluctantly, he repeats, because the necessity makes him sensible that he can have succeeded but imperfectly, at best, in throwing about this Romance the kind of atmosphere essential to the effect at which he aimed.
He designed the story and the characters to bear, of course, a certain relation to human nature and human life, but still to be so artfully and airily removed from our mundane sphere, that some laws and proprieties of their own should be implicitly and insensibly acknowledged.
The idea of the modern Faun, for example, loses all the poetry and beauty which the Author fancied in it, and becomes nothing better than a grotesque absurdity, if we bring it into the actual light of day. He had hoped to mystify this anomalous creature between the Real and the Fantastic, in such a manner that the reader’s sympathies might be excited to a certain pleasurable degree, without impelling him to ask how Cuvier would have classified poor Donatello, or to insist upon being told, in so many words, whether he had furry ears or no. As respects all who ask such questions, the book is, to that extent, a failure.
Nevertheless, the Author fortunately has it in his power to throw light upon several matters in which some of his readers appear to feel an interest. To confess the truth, he was himself troubled with a curiosity similar to that which he has just deprecated on the part of his readers, and once took occasion to cross-examine his friends, Hilda and the sculptor, and to pry into several dark recesses of the story, with which they had heretofore imperfectly acquainted him.
We three had climbed to the top of St. Peter’s, and were looking down upon the Rome we were soon to leave, but which (having already sinned sufficiently in that way) it is not my purpose further to describe. It occurred to me, that, being so remote in the upper air, my friends might safely utter here the secrets which it would be perilous even to whisper on lower earth.
“Hilda,” I began, “can you tell me the contents of that mysterious packet which Miriam entrusted to your charge, and which was addressed to Signore Luca Barboni, at the Palazzo Cenci?”
“I never had any further knowledge of it,” replied Hilda, “nor felt it right to let myself be curious upon the subject.”
“As to its precise contents,” interposed Kenyon, “it is impossible to speak. But Miriam, isolated as she seemed, had family connections in Rome, one of whom, there is reason to believe, occupied a position in the papal government.
“This Signore Luca Barboni was either the assumed name of the personage in question, or the medium of communication between that individual and Miriam. Now, under such a government as that of Rome, it is obvious that Miriam’s privacy and isolated life could only be maintained through the connivance and support of some influential person connected with the administration of affairs. Free and self-controlled as she appeared, her every movement was watched and investigated far more thoroughly by the priestly rulers than by her dearest friends.
“Miriam, if I mistake not, had a purpose to withdraw herself from this irksome scrutiny, and to seek real obscurity in another land; and the packet, to be delivered long after her departure, contained a reference to this design, besides certain family documents, which were to be imparted to her relative as from one dead and gone.”
“Yes, it is clear as a London fog,” I remarked. “On this head no further elucidation can be desired. But when Hilda went quietly to deliver the packet, why did she so mysteriously vanish?”
“You must recollect,” replied Kenyon, with a glance of friendly commiseration at my obtuseness, “that Miriam had utterly disappeared, leaving no trace by which her whereabouts could be known. In the meantime, the municipal authorities had become aware of the murder of the Capuchin; and from many preceding circumstances, such as his persecution of Miriam, they must have seen an obvious connection between herself and that tragical event. Furthermore, there is reason to believe that Miriam was suspected of connection with some plot, or political intrigue, of which there may have been tokens in the packet. And when Hilda appeared as the bearer of this missive, it was really quite a matter of course, under a despotic government, that she should be detained.”
“Ah, quite a matter of course, as you say,” answered I.  But there are other riddles. On the night of the extinction of the lamp, you met Donatello, in a penitent’s garb, and afterwards saw and spoke to Miriam, in a coach, with a gem glowing on her bosom. What was the business of these two guilty ones in Rome, and who was Miriam’s companion?”
“Who!” repeated Kenyon, “why, her official relative, to be sure; and as to their business, Donatello’s still gnawing remorse had brought him hitherward, in spite of Miriam’s entreaties, and kept him lingering in the neighborhood of Rome, with the ultimate purpose of delivering himself up to justice. Hilda’s disappearance, which took place the day before, was known to them through a secret channel, and had brought them into the city, where Miriam, as I surmise, began to make arrangements, even then, for that sad frolic of the Carnival.”
“And where was Hilda all that dreary time between?” inquired I.
“Where were you, Hilda?” asked Kenyon, smiling.
Hilda threw her eyes on all sides, and seeing that there was not even a bird of the air to fly away with the secret, nor any human being nearer than the loiterers by the obelisk in the piazza below, she told us about her mysterious abode.
“I was a prisoner in the Convent of the Sacre Coeur, in the Trinita de Monte,” said she, “but in such kindly custody of pious maidens, and watched over by such a dear old priest, that—had it not been for one or two disturbing recollections, and also because I am a daughter of the Puritans I could willingly have dwelt there forever. My entanglement with Miriam’s misfortunes, and the good abbate’s mistaken hope of a proselyte, seem to me a sufficient clew to the whole mystery.”
“The atmosphere is getting delightfully lucid,” observed I, “but there are one or two things that still puzzle me. Could you tell me—and it shall be kept a profound secret, I assure you what were Miriam’s real name and rank, and precisely the nature of the troubles that led to all those direful consequences?”
“Is it possible that you need an answer to those questions?” exclaimed Kenyon, with an aspect of vast surprise. “Have you not even surmised Miriam’s name? Think awhile, and you will assuredly remember it. If not, I congratulate you most sincerely; for it indicates that your feelings have never been harrowed by one of the most dreadful and mysterious events that have occurred within the present century!”
“Well,” resumed I, after an interval of deep consideration, “I have but few things more to ask. Where, at this moment, is Donatello?”
“The Castle of Saint Angelo,” said Kenyon sadly, turning his face towards that sepulchral fortress, “is no longer a prison; but there are others which have dungeons as deep, and in one of them, I fear, lies our poor Faun.”
“And why, then, is Miriam at large?” I asked.
“Call it cruelty if you like, not mercy,” answered Kenyon. “But, after all, her crime lay merely in a glance. She did no murder!”
“Only one question more,” said I, with intense earnestness. “Did Donatello’s ears resemble those of the Faun of Praxiteles?”
“I know, but may not tell,” replied Kenyon, smiling mysteriously. “On that point, at all events, there shall be not one word of explanation.”
Leamington, March 14, 1860.


2019-03-24 跨文化比较（五）：中西方婚姻观 Cross-cultural Comparison(5): Chinese and Western Views on Marriage cn-curation
2019-03-18 跨文化比较（四）：中国人的“和”、“合”与西方人的“独”、“立” Cross-cultural Comparison (4): the Harmony and Integration of the Chinese and the “Individualism” and Independence of the Westerners cn-curation
2019-03-16 跨文化比较（三）：日本人的死板与中国人的灵活 Cross-cultural Comparison(3): Inflexible Japanese and Flexible Chinese cn-curation
2018-05-15 由《骆驼》英译文比较汉语和英语的区别 A Comparison of the Difference Between Chinese and English from the English Translation of the Camel writing


--- layout: documentation title: AccessedFileListType ---
The AccessedFileListType specifies a list of files accessed by a prefetch application.
| Field Name | Type | Description |
|---|---|---|
| Accessed_Filename1..n | StringObjectPropertyType |
Specifies the filename of the accessed file. |


CryptoHack - General
- ASCII - Points: 5
- Hex - Points: 5
- Base64 - Points: 10
- Bytes and Big Integers - Points: 10
- Encoding Challenge - Points: 40
Table of Contents
Encoding
- ASCII - Points: 5
-
ASCII is a 7-bit encoding standard which allows the representation of text using the integers 0-127. Using the below integer array, convert the numbers to their corresponding ASCII characters to obtain a flag.
[99,114,121,112,116,111,123, 65,83,67,73,73,95,112,114, 49,110,116,52,98,108,51,125]
ASCII = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114,
49, 110, 116, 52, 98, 108, 51, 125]
flag = ''
for c in ASCII:
flag += chr(c)
print(flag)
-
Convert each integer to character to get the flag
$ python3 ascii.py
# crypto{ASCII_pr1nt4bl3}
crypto{ASCII_pr1nt4bl3}
- Hex - Points: 5
-
When we encrypt something the resulting ciphertext commonly has bytes which are not printable ASCII characters. If we want to share our encrypted data, it's common to encode it into something more user-friendly and portable across different systems. Included below is a the flag encoded as a hex string. Decode this back into bytes to get the flag.
63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d
from binascii import unhexlify
flag = unhexlify(b'63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d')
print(flag)
-
Decode hex to get the flag
$ python3 hex.py
# b'crypto{You_will_be_working_with_hex_strings_a_lot}'
crypto{You_will_be_working_with_hex_strings_a_lot}
- Base64 - Points: 10
-
Another common encoding scheme is Base64, which allows us to represent binary data as an ASCII string using 64 characters. One character of a Base64 string encodes 6 bits, and so 4 characters of Base64 encodes three 8-bit bytes. Base64 is most commonly used online, where binary data such as images can be easy included into html or css files. Take the below hex string, decode it into bytes and then encode it into Base64.
72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf
import base64
from binascii import unhexlify
hex = unhexlify('72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf')
flag = base64.b64encode(hex)
print(flag)
-
First of all decode hex, then encode into base64 to get the flag
$ python3 base.py
# b'crypto/Base+64+Encoding+is+Web+Safe/'
crypto/Base+64+Encoding+is+Web+Safe/
- Bytes and Big Integers - Points: 10
- Cryptosystems like RSA works on numbers, but messages are made up of characters. How should we convert our messages into numbers so that mathematical operations can be applied? The most common way is to take the ordinal bytes of the message, convert them into hexadecimal, and concatenate. This can be interpreted as a base-16 number, and also represented in base-10. To illustrate:
message: HELLO
ascii bytes: [72, 69, 76, 76, 79]
hex bytes: [0x48, 0x45, 0x4c, 0x4c, 0x4f]
base-16: 0x48454c4c4f
base-10:<PHONE_NUMBER>87
-
Python's PyCryptodome library implements this with the methods
bytes_to_long
andlong_to_bytes
from Crypto.Util.number.
Convert the following integer back into a message
11515195063862318899931685488813747395775516287289682636499965282714637259206269
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import long_to_bytes
data =<PHONE_NUMBER>3862318899931685488813747395775516287289682636499965282714637259206269
bytes = long_to_bytes(data)
print(bytes)
-
Simply convert long to byte with the respectively function to get the flag
$ python3 flag.py
# b'crypto{3nc0d1n6_4ll_7h3_w4y_d0wn}'
crypto{3nc0d1n6_4ll_7h3_w4y_d0wn}
- Encoding Challenge - Points: 40
-
Now you've got the hang of the various encodings you'll be encountering, let's have a look at automating it. Can you pass all 100 levels to get the flag? The 13377.py file attached below is the source code for what's running on the server. The pwntools_example.py file provides the start of a solution using the incredibly convenient pwntools library, which you can use if you like (we prefer it over the telnetlib library, however it's not compatible with Windows). If you're having trouble getting pwntools to work, then you might want to try basing your answer on the script provided in the Introduction "Network Attacks" challenge instead.
Connect at
nc socket.cryptohack.org 13377
Source code on the server
#!/usr/bin/env python3
from Crypto.Util.number import bytes_to_long, long_to_bytes
from utils import listener # this is cryptohack's server-side module and not part of python
import base64
import codecs
import random
FLAG = "crypto{????????????????????}"
ENCODINGS = [
"base64",
"hex",
"rot13",
"bigint",
"utf-8",
]
with open('/usr/share/dict/words') as f:
WORDS = [line.strip().replace("'", "") for line in f.readlines()]
class Challenge():
def __init__(self):
self.challenge_words = ""
self.stage = 0
def create_level(self):
self.stage += 1
self.challenge_words = "_".join(random.choices(WORDS, k=3))
encoding = random.choice(ENCODINGS)
if encoding == "base64":
encoded = base64.b64encode(self.challenge_words.encode()).decode() # wow so encode
elif encoding == "hex":
encoded = self.challenge_words.encode().hex()
elif encoding == "rot13":
encoded = codecs.encode(self.challenge_words, 'rot_13')
elif encoding == "bigint":
encoded = hex(bytes_to_long(self.challenge_words.encode()))
elif encoding == "utf-8":
encoded = [ord(b) for b in self.challenge_words]
return {"type": encoding, "encoded": encoded}
#
# This challenge function is called on your input, which must be JSON
# encoded
#
def challenge(self, your_input):
if self.stage == 0:
return self.create_level()
elif self.stage == 100:
self.exit = True
return {"flag": FLAG}
if self.challenge_words == your_input["decoded"]:
return self.create_level()
return {"error": "Decoding fail"}
listener.start_server(port=13377)
-
As we can notice from the code above, what happens on the server is: there are 100 stages, at each stage a string is composed by linking 3 randomly words together, where the words come from a list of them read by an external file; the string is then encrypted in some way and finally sent back.
At each iteration the server also check our answer, basically we need to decode the string and send it back. If we are able to decode all the 100 stages we get our flag
from pwn import * # pip install pwntools
import json
from Crypto.Util.number import bytes_to_long, long_to_bytes
import base64
import codecs
import random
from binascii import unhexlify
r = remote('socket.cryptohack.org', 13377, level = 'debug')
def json_recv():
line = r.recvline()
return json.loads(line.decode())
def json_send(hsh):
request = json.dumps(hsh).encode()
r.sendline(request)
def list_to_string(s):
output = ""
return(output.join(s))
for i in range(0,101):
received = json_recv()
if "flag" in received:
print("\n[*] FLAG: {}".format(received["flag"]))
break
print("\n[-] Cycle: {}".format(i))
print("[-] Received type: {}".format(received["type"]))
print("[-] Received encoded value: {}".format(received["encoded"]))
word = received["encoded"]
encoding = received["type"]
if encoding == "base64":
decoded = base64.b64decode(word).decode('utf8').replace("'", '"')
elif encoding == "hex":
decoded = (unhexlify(word)).decode('utf8').replace("'", '"')
elif encoding == "rot13":
decoded = codecs.decode(word, 'rot_13')
elif encoding == "bigint":
decoded = unhexlify(word.replace("0x", "")).decode('utf8').replace("'", '"')
elif encoding == "utf-8":
decoded = list_to_string([chr(b) for b in word])
print("[-] Decoded: {}".format(decoded))
print("[-] Decoded Type: {}".format(type(decoded)))
to_send = {
"decoded": decoded
}
json_send(to_send)
$ python3 pwntools_example_f93ca6ccef2def755aa8f6d9aa6e9c5b.py
# [+] Opening connection to socket.cryptohack.org on port 13377: Done
# [DEBUG] Received 0x3e bytes: b'{"type": "rot13", "encoded": "pbafgnapl_rssrzvanpl_cerccvre"}\n'
# [-] Cycle: 0
# [-] Received type: rot13
# [-] Received encoded value: pbafgnapl_rssrzvanpl_cerccvre
# [-] Decoded: constancy_effeminacy_preppier
# [-] Decoded Type: <class 'str'>
# [DEBUG] Sent 0x2d bytes: b'{"decoded": "constancy_effeminacy_preppier"}\n'
# ...
# ...
# [*] FLAG: crypto{3nc0d3_d3c0d3_3nc0d3}
crypto{3nc0d3_d3c0d3_3nc0d3}
- XOR Starter - Points: 10
- XOR is a bitwise operator which returns 0 if the bits are the same, and 1 otherwise. In textbooks the XOR operator is denoted by ⊕, but in most challenges and programming languages you will see the caret ^ used instead.
-
For binary strings we XOR bit by bit:
b'0110' ^ b'1010' = b'1100'
. We can XOR integers by first converting the integer from decimal to binary. We can XOR strings by first converting each character to the integer representing the Unicode character. Given the string"label"
XOR each character with the integer13
. Convert these integers back to a string and submit the flag as codecrypto{new_string}.
data = "label"
flag = ''
for c in data:
flag += chr(ord(c) ^ 13)
print('crypto{{{}}}'.format(flag))
-
Read character by character and do the xor between the integer value of each character and 13
$ python3 flag.py
crypto{aloha}
crypto{aloha}
- XOR Properties - Points: 15
-
In the last challenge, you saw how XOR worked at the level of bits. In this one, we're going to cover the properties of the XOR operation and then use them to undo a chain of operations that have encrypted a flag. Gaining an intuition for how this works will help greatly when you come to attacking real cryptosystems later, especially in the block ciphers category.
There are four main properties we should consider when we solve challenges using the XOR operator
Commutative: A ⊕ B = B ⊕ A
Associative: A ⊕ (B ⊕ C) = (A ⊕ B) ⊕ C
Identity: A ⊕ 0 = A
Self-Inverse: A ⊕ A = 0
-
Let's break this down. Commutative means that the order of the XOR operations is not important. Associative means that a chain of operations can be carried out without order (we do not need to worry about brackets). The identity is 0, so XOR with 0 "does nothing", and lastly something XOR'd with itself returns zero.
Let's try this out in action! Below is a series of outputs where three random keys have been XOR'd together and with the flag. Use the above properties to undo the encryption in the final line to obtain the flag.
KEY1 = a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313
KEY2 ^ KEY1 = 37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e
KEY2 ^ KEY3 = c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1
FLAG ^ KEY1 ^ KEY3 ^ KEY2 = 04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf
Hint: Before you XOR these objects, be sure to decode from hex to bytes. If you have pwntools installed, you have a xor function for byte strings: from pwn import xor
#!/usr/bin/env python3
from binascii import unhexlify
def xor_two_str(s1,s2):
if len(str1) != len(str2):
raise "XOR EXCEPTION: Strings are not of equal length!"
return ''.join(format(int(a, 16) ^ int(b, 16), 'x') for a,b in zip(s1,s2))
KEY1 = "a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313"
KEY2 = xor_two_str("37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e", KEY1)
print("[-] KEY2: {}".format(KEY2))
KEY3 = xor_two_str("c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1", KEY2)
print("[-] KEY3: {}".format(KEY3))
KEY4 = xor_two_str(xor_two_str(KEY1, KEY2), KEY3)
print("[-] KEY4: {}\n".format(KEY4))
FLAG = xor_two_str("04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf", KEY4)
print("[*] FLAG: {}".format(unhexlify(FLAG)))
-
As we can see from the proposed keys, the only applicable property is the commutative one. Let's apply it to get KEY2 from KEY1 and then do the same for the remaining KEYs. Finally we get the flag in hex format, decoding it we get the flag
$ python3 flag.py
# [-] KEY2: 911404e13f94884eabbec925851240a52fa381ddb79700dd6d0d
# [-] KEY3: 504053b757eafd3d709d6339b140e03d98b9fe62b84add0332cc
# [-] KEY4: 679ce12554e557ada0e38f2e52f126e54240b2576c83c4196cd2
#
# [*] FLAG: b'crypto{x0r_i5_ass0c1at1v3}'
crypto{x0r_i5_ass0c1at1v3}
- Favourite byte - Points: 20
-
I've hidden my data using XOR with a single byte. Don't forget to decode from hex first.
73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d
from binascii import unhexlify
import string
def single_byte_xor(input, key):
if len(chr(key)) != 1:
raise "KEY LENGTH EXCEPTION: In single_byte_xor key must be 1 byte long!"
output = b''
for b in input:
output += bytes([b ^ key])
try:
return output.decode("utf-8")
except:
return "Cannot Decode some bytes"
data = "73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d"
decoded = unhexlify(data)
print("[-] HEX_DECODE: {}\n".format(decoded))
result = {}
for i in range(256):
result[i] = (single_byte_xor(decoded, i))
#print("[-] KEY: {}\nSTRING: {}".format(i,single_byte_xor(decoded, i)))
print("[*] FLAG: {}".format([s for s in result.values() if "crypto" in s]))
-
This is a single byte XOR-cypher. In order to break it we need to xor each single byte of our decoded data with one single byte at time. Iterating through all the possible bytes we finally get our flag
$ python3 flag.py
# [-] HEX_DECODE: b"sbi`d\x7fk h! O!%O}iOv$f eb!'#Ori'um"
# ...
# [*] FLAG: ['crypto{0x10_15_my_f4v0ur173_by7e}']
crypto{0x10_15_my_f4v0ur173_by7e}
- You either know, XOR you don't - Points: 30
-
I've encrypted the flag with my secret key, you'll never be able to guess it
e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104
Hint: Remember the flag format and how it might help you in this challenge!
from binascii import unhexlify
def brute(input, key):
if len(input) != len(key):
return "Failed!"
output = b''
for b1, b2 in zip(input, key):
output += bytes([b1 ^ b2])
try:
return output.decode("utf-8")
except:
return "Cannot Decode some bytes"
data = "0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104"
cipher = unhexlify(data)
print("[-] CIPHER: {}".format(cipher))
# First Step
key_part = brute(cipher[:7], "crypto{".encode())
print("[-] PARTIAL KEY FOUND: {}".format(key_part))
# Second Step
key = (key_part + "y").encode()
key += key * int((len(cipher) - len(key))/len(key))
key += key[:((len(cipher) - len(key))%len(key))]
print("[-] Decoding using KEY: {}".format(key))
plain = brute(cipher, key)
print("\n[*] FLAG: {}".format(plain))
-
We know that is a XOR-cipher, the first thing we can try, as suggested, it's to look for a part of the key by xoring the first seven character of the FLAG which is
"crypto{"
and the same number of character from our ciphertext (code section "First Step"). As result we have
"myXORke"
. By using not so much immgination we can try myXORkey as key and by repeating it over the lenght of our ciphertext and xoring with all the cipher we get our flag (code section "Second Step").
$ python3 flag.py
# [-] CIPHER: # b"\x0e\x0b!?&\x04\x1eH\x0b&!\x7f'4.\x17]\x0e\x07\n<[\x10>%&!\x7f'4.\x17]\x0e\x07~&4Q\x15\x01\x04"
# [-] PARTIAL KEY FOUND: myXORke
# [-] Decoding using KEY: b'myXORkeymyXORkeymyXORkeymyXORkeymyXORkeymy'
# ...
# [*] FLAG: crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll}
crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll}
- Greatest Common Divisor - Points: 15
- The Greatest Common Divisor (GCD), sometimes known as the highest common factor, is the largest number which divides two positive integers (a,b). For a = 12, b = 8 we can calculate the divisors of a: {1,2,3,4,6,12} and the divisors of b: {1,2,4,8}. Comparing these two, we see that gcd(a,b) = 4. Now imagine we take a = 11, b = 17. Both a and b are prime numbers. As a prime number has only itself and 1 as divisors, gcd(a,b) = 1. We say that for any two integers a,b, if gcd(a,b) = 1 then a and b are coprime integers. If a and b are prime, they are also coprime. If a is prime and b < a then a and b are coprime.
Hint: Think about the case for a prime and b > a, why are these not necessarily coprime?
-
There are many tools to calculate the GCD of two integers, but for this task we recommend looking up Euclid's Algorithm. Try coding it up; it's only a couple of lines. Use a = 12, b = 8 to test it. Now calculate gcd(a,b) for a = 66528, b = 52920 and enter it below.
def euclid_gcd(x, y):
if x < y:
return euclid_gcd(y, x)
while y != 0:
(x, y) = (y, x % y)
print("\n[+] GCD: {}".format(x))
return x
# a = 12
# b = 8
a = 66528
b = 52920
euclid_gcd(a, b)
-
Simply calculate the GCD using the Euclidean algorithm.
$ python3 flag.py
# [+] GCD: 1512
1512
- Extended GCD - Points: 20
-
Let a and b be positive integers.
The extended Euclidean algorithm is an efficient way to find integers u,v such that:
a * u + b * v = gcd(a,b)
Hint: Later, when we learn to decrypt RSA, we will need this algorithm to calculate the modular inverse of the public exponent.
-
Using the two primes p = 26513, q = 32321, find the integers u,v such that:
p * u + q * v = gcd(p,q)
Hint: Knowing that p,q are prime, what would you expect gcd(p,q) to be?
def extended_gcd(p,q):
if p == 0:
return (q, 0, 1)
else:
(gcd, u, v) = extended_gcd(q % p, p)
return (gcd, v - (q // p) * u, u)
p = 26513
q = 32321
gcd, u, v = extended_gcd(p, q)
print("[+] GCD: {}".format(gcd))
print("[+] u,v: {},{}".format(u,v))
print("\n[*] FLAG: crypto{{{},{}}}".format(u,v))
$ python3 flag.py
# [+] GCD: 1
# [+] u,v: 10245,-8404
#
# [*] FLAG: crypto{10245,-8404}
crypto{10245,-8404}


UFF Operators¶
All shapes include batch dimension, unless otherwise specified.
Input¶
An input to the network. Expects a CHW shape.
Supported Datatypes¶
float32, float16, int32, int8
Identity¶
Identity layer.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| Input0 to the identity. Must be float32. |
Supported Datatypes¶
float32
Const¶
A constant in the network. Should not include batch dimension.
Supported Datatypes¶
float32, float16, int32, int8
Conv¶
A convolution operation.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the convolution. Must be 4 dimensional. Automatically transposed to NCHW. | |
| Kernel [Constant]: | |
| The kernel weights for the convolution. Must be 4 dimensional. Automatically transposed to NCHW. |
Attributes¶
| dilation [List[int]]: | |
|---|---|
| The HW dilations. | |
| strides [List[int]]: | |
| The HW strides. | |
| padding [List[int]]: | |
| The HW padding. Asymmetric padding is unsupported. |
Supported Datatypes¶
float32, float16, int32, int8
ConvTranspose¶
A transposed convolution, also known as deconvolution.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the transposed convolution. Must be 4 dimensional. Automatically transposed to NCHW. | |
| Kernel [Constant]: | |
| The kernel weights for the transposed convolution. Must be 4 dimensional. Automatically transposed to NCHW. | |
| Shape [Constant]: | |
| The HW dimensions of the output. |
Attributes¶
| strides [List[int]]: | |
|---|---|
| The HW strides. | |
| padding [List[int]]: | |
| The HW padding. Asymmetric padding is unsupported. |
Supported Datatypes¶
float32, float16, int32, int8
Pool¶
A pooling layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the pooling layer. Must be 4 dimensional. |
Attributes¶
| func [Enum[max, avg]]: | |
|---|---|
| The type of pooling to apply. | |
| kernel [List[int]]: | |
| The HW shape of the kernel. | |
| strides [List[int]]: | |
| The HW strides. | |
| padding [List[int]]: | |
| The HW padding. |
Supported Datatypes¶
float32, float16, int32, int8
FullyConnected¶
A fully connected layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the fully connected layer. Must be at least 4 dimensional. Automatically transposed to -NC-. | |
| Weights [Constant]: | |
| The weights for the fully connected layer. Must be 3 dimensional. Automatically transposed to CHW, where C is the number of output channels. |
Supported Datatypes¶
float32, float16, int32, int8
LRN¶
An LRN layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the LRN. Must be at least 4 dimensional. |
Attributes¶
| window_size [int]: | |
|---|---|
| The window size. | |
| alpha [double]: | The LRN alpha value. |
| beta [double]: | The LRN beta value. |
| k [double]: | The LRN k value. |
Supported Datatypes¶
float32, float16, int32, int8
Binary¶
A binary layer.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The first input to the binary layer. | |
| Input1 [Tensor or Constant]: | |
| The second input to the binary layer. |
If either input is a constant, then at least one of the inputs must be 4 dimensional.
Attributes¶
| func [Enum[min, max, mul, sub, div, add, pow]]: | |
|---|---|
| The type of operation to perform. |
Supported Datatypes¶
float32, float16, int32, int8
Unary¶
A unary layer.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The input to the unary layer. |
The output of a unary layer with a Constant input is treated as a Constant, and therefore will not work with layers expecting a Tensor input.
Attributes¶
| func [Enum[neg, exp, log, abs, sqrt, rsqrt, square, sin, cos, tan, sinh, cosh, asin, acos, atan, asinh, acosh, atanh, ceil, floor]]: | |
|---|---|
| The type of operation to perform. |
Supported Datatypes¶
float32, float16, int32, int8
Reshape¶
A reshape layer. NOTE: this layer destroys order information. Therefore, subsequent layers will cease to automatically transpose their inputs to the correct format.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The input to the reshape layer. | |
| Shape [Constant]: | |
| The desired shape. If the shape has fewer than 3 non-batch dimensions, 1s are inserted in the least significant dimensions. For example, if the shape specified is [1, 300, 5], it will be treated as [1, 300, 5, 1] instead. - -1 specifies that the dimension should be automatically deduced - this can only be used at most once in any given shape. - 0 specifies that the dimension should be copied from the input. |
The output of a reshape layer with a Constant input is treated as a Constant, and therefore will not work with layers expecting a Tensor input.
Supported Datatypes¶
float32, float16, int32, int8
ExpandDims¶
An unsqueeze layer. NOTE: this layer destroys order information. Therefore, subsequent layers will cease to automatically transpose their inputs to the correct format.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to unsqueeze. |
If the resulting output has fewer than 3 non-batch dimensions, it is unsqueezed further with additional 1s inserted in the least significant dimensions. For example, with an input of shape [1, 300], and axis of 1, the shape of the output will be [1, 300, 1, 1] rather than [1, 300, 1].
Attributes¶
| axis [int]: | The axis on which to unsqueeze, excluding batch dimension. For example, unsqueezing an NCHW tensor with an axis of 0 will result in a N1CHW tensor. |
|---|
Supported Datatypes¶
float32, float16, int32, int8
ArgMax¶
An argmax layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the argmax layer. |
Attributes¶
| axis [int]: | The axis on which to perform the argmax, with 0 corresponding to the batch dimension. The specified dimension is removed. For example, performing argmax on an input of shape [1, 300, 150], with an axis of 1 would result in an output of shape [1, 150]. NOTE: argmax on the batch dimension is not supported. |
|---|
Supported Datatypes¶
float32, float16, int32, int8
ArgMin¶
An argmin layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the argmin layer. |
Attributes¶
| axis [int]: | The axis on which to perform the argmin, with 0 corresponding to the batch dimension. The specified dimension is removed. For example, performing argmin on an input of shape [1, 300, 150], with an axis of 1 would result in an output of shape [1, 150]. NOTE: argmin on the batch dimension is not supported. |
|---|
Supported Datatypes¶
float32, float16, int32, int8
Transpose¶
A transpose layer. A no-op in the network, this layer only modifies the UFF parser’s internal order information. Therefore, when followed by any layer that destroys order information, the transpose will not be performed.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the transpose layer. |
Attributes¶
| permutation [int]: | |
|---|---|
| The permutation to perform. Must be 4 dimensional. |
Supported Datatypes¶
float32, float16, int32, int8
Reduce¶
A reduce layer. NOTE: this layer destroys order information. Therefore, subsequent layers will cease to automatically transpose their inputs to the correct format.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The input to the reduce layer. |
The output of a reduce layer with a Constant input is treated as a Constant, and therefore will not work with layers expecting a Tensor input.
Attributes¶
| func [Enum[sum, prod, max, min, mean]]: | |
|---|---|
| The reduction operation to perform. | |
| axes [List[int]]: | |
| The axes on which to reduce, with 0 corresponding to the batch dimension. Reduction on the batch dimension is unsupported. | |
| keepdims [bool]: | |
| Whether to keep the dimensions which were reduced. NOTE: The UFF parser ignored this value, and always keeps dimensions. |
Supported Datatypes¶
float32, float16, int32, int8
Concat¶
A concatenation layer.
Inputs¶
| Inputs (variadic) [List[Tensor]]: | |
|---|---|
| The tensors to concatenate. All inputs are transposed to the same format as the first input. Inputs must be at least 4 dimensional. |
Attributes¶
| axis [int]: | The axis on which to perform the concatenation, with 0 corresponding to the batch dimension. Concatenating on the batch dimension is unsupported. |
|---|
Supported Datatypes¶
float32, float16, int32, int8
MarkOutput¶
The output of the network.
Inputs¶
| Inputs (variadic) [List[Tensor]]: | |
|---|---|
| The inputs to this layer. Automatically transposed to the same order as the outputs of the original TensorFlow network. |
Supported Datatypes¶
float32, float16, int32, int8
Activation¶
An activation layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the activation. |
Attributes¶
| func [Enum[relu, relu6, sigmoid, tanh, elu, selu, softsign, softplus]]: | |
|---|---|
| The operation to perform. |
Supported Datatypes¶
float32, float16, int32, int8
Softmax¶
A softmax layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the softmax. |
Attributes¶
| axis [int]: | The axis on which to perform the reduction. NOTE: This value is ignored by the UFF parser. |
|---|
Supported Datatypes¶
float32, float16, int32, int8
BatchNorm¶
A batchnorm layer.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the batchnorm. Must be 4 dimensional. | |
| Gamma [Constant]: | |
| The gamma values. | |
| Beta [Constant]: | |
| The beta values. | |
| Mean [Constant]: | |
| The mean values. | |
| Variance [Constant]: | |
| The variance values. |
Attributes¶
| epsilon [double]: | |
|---|---|
| The epsilon value. |
Supported Datatypes¶
float32, float16, int32, int8
Shape¶
A shape layer. Returns the shape of its input. NOTE: the output of this layer is a Constant, and therefore will not work with layers expecting a Tensor input.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The input to the shape layer. |
Supported Datatypes¶
float32, float16, int32, int8
StridedSlice¶
A strided slice layer.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The input to the strided slice. | |
| Begin [Constant]: | |
| The indices at which to begin slicing. | |
| End [Constant]: | The indices at which to end slicing. |
| Strides [Constant]: | |
| Strides to use when slicing. |
Attributes¶
| begin_mask [int]: | |
|---|---|
| See TensorFlow stridedSlice documentation. | |
| end_mask [int]: | See TensorFlow stridedSlice documentation. |
| shrink_axis_mask [int]: | |
| See TensorFlow stridedSlice documentation. This value is ignored unless the input is a constant. |
Supported Datatypes¶
float32, float16, int32, int8
Stack¶
A stack layer. NOTE: the output of this layer is a Constant, and therefore will not work with layers expecting a Tensor input.
Inputs¶
| Inputs (variadic) [List[Constant]]: | |
|---|---|
| The inputs to the stack layer. |
Attributes¶
| axis [int]: | The axis on which to stack. NOTE: this value is ignored by the UFF parser. |
|---|
Supported Datatypes¶
float32, float16, int32, int8
Squeeze¶
Not implemented
Flatten¶
A flatten layer. A no-op in the UFF parser.
Inputs¶
| Input0 [Tensor]: | |
|---|---|
| The tensor to flatten. |
Supported Datatypes¶
float32, float16, int32, int8
Pad¶
A padding layer.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The input to pad. The input is automatically transposed if padding is applied to non-HW dimensions. | |
| Padding [Constant]: | |
| The padding to apply. Padding is supported on 2 dimensions at most. |
The output of a padding layer with a Constant input is treated as a Constant, and therefore will not work with layers expecting a Tensor input.
Supported Datatypes¶
float32, float16, int32, int8
Gather¶
A gather layer.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The input to the gather layer. If the input is constant, it is assumed to be of shape NC11. | |
| Indices [Tensor or Constant]: | |
| The indices to gather along. These are assumed to be on the first non-batch dimension. |
Supported Datatypes¶
float32, float16, int32, int8
GatherV2¶
A gatherV2 layer.
Inputs¶
| Input0 [Tensor or Constant]: | |
|---|---|
| The input to the gather layer. If the input is constant, it is assumed to be of shape NC11. | |
| Indices [Tensor or Constant]: | |
| The indices to gather along. |
Attributes¶
| axis [int]: | The axis along which to gather, excluding batch dimension. |
|---|
Supported Datatypes¶
float32, float16, int32, int8


The CodeNarc Eclipse plug-in integrates the source code analyzer CodeNarc into Eclipse.
CodeNarc is a static analysis tool for Groovy source code, enabling monitoring and enforcement of many coding standards and best practices. CodeNarc applies predefined and/or custom rules to each Groovy file, and generates an HTML or XML report.
| Release | http://codenarceclipse.sourceforge.net/eclipse/release/ |
| Snapshot | http://codenarceclipse.sourceforge.net/eclipse/snapshot/ |
Supported Eclipse versions: 3.5, 3.6, 3.7 and 4.2
Currently all rulesets that ship with CodeNarc are used to check for violations.
CodeNarc is only enabled for projects having the Groovy nature.
You can mark .groovy files or a Groovy project and check the code with CodeNarc.
In case of violations, CodeNarc markers are added to the editor and "Problems" view.
Version 0.21.0 (2014-08-03)
Version 0.20.0 (2013-12-23)
Version 0.19.0 (2013-08-04)
Version 0.18.2 (2013-04-03)
Version 0.18.1 (2013-01-06)
Version 0.18.0 (2012-12-23)
Version 0.17.0 (2012-04-23)
Version 0.16.1 (2011-12-26)
Version 0.15.0 (2011-08-15)
Version 0.14.0 (not released)


--- layout: page title: Facilities script: facilities.js --- {% include description.html data = site.data.facilities %} {% include cards.html data = site.data.facilities %} {% include sections.html data = site.data.facilities %}


INSTRUCTIONS
1. Queue first song (double tap to add)
2. Open playlist in Spotify using the link below (if not loading, open Spotify and go to the 'PointOfQueue' playlist)
3. Start the queue by pressing play on the first song
NOTE: Steps 2 & 3 only need to be done for the first song of a queue, subsequent songs can be added with just Step 1
INSTRUCTIONS
1. Wait for room owner to start queue
2. Queue a song (double tap to add)
Point of Queue lets you to create a Spotify (premium) queue that allows others to add songs!
Perfect for car rides, parties, etc.


| Modifier and Type | Class and Description |
|---|---|
class |
DeploymentOptionSection
The DeploymentOptionSection specifies a discrete set of intended resource configurations.
|
class |
DiskSection
A DiskSection describes meta-information about virtual disks in the OVF package.
|
class |
NetworkSection
The NetworkSection element shall list all logical networks used in the OVF package.
|
class |
OperatingSystemSection
An OperatingSystemSection specifies the operating system installed on a virtual machine.
|
class |
ProductSection
The ProductSection element specifies product-information for an appliance, such as product name,
version, and vendor.
|
class |
StartupSection
Specifies the order in which entities in a VirtualSystemCollection are powered on and shut down
|
class |
VirtualHardwareSection
The virtual hardware required by a virtual machine is specified in VirtualHardwareSection.
|
| Modifier and Type | Method and Description |
|---|---|
abstract SectionType |
SectionType.Builder.build() |
| Modifier and Type | Method and Description |
|---|---|
B |
SectionType.Builder.fromSectionType(SectionType in) |
| Modifier and Type | Class and Description |
|---|---|
class |
BaseVirtualSystem |
| Modifier and Type | Field and Description |
|---|---|
protected Set<SectionType> |
BaseEnvelope.Builder.additionalSections |
| Modifier and Type | Method and Description |
|---|---|
Set<SectionType> |
BaseVirtualSystem.getAdditionalSections() |
Set<SectionType> |
BaseEnvelope.getAdditionalSections() |
| Modifier and Type | Method and Description |
|---|---|
B |
BaseVirtualSystem.Builder.additionalSection(SectionType additionalSection) |
B |
BaseEnvelope.Builder.additionalSection(SectionType additionalSection) |
| Modifier and Type | Method and Description |
|---|---|
B |
BaseVirtualSystem.Builder.additionalSections(Iterable<? extends SectionType> additionalSections) |
B |
BaseEnvelope.Builder.additionalSections(Iterable<? extends SectionType> additionalSections) |
| Modifier and Type | Method and Description |
|---|---|
Set<SectionType> |
VAppTemplate.getSections()
Contains ovf sections for vApp template.
|
Set<SectionType> |
AbstractVAppType.getSections()
Specific
ovf:Section with additional information for the vApp. |
| Modifier and Type | Method and Description |
|---|---|
B |
AbstractVAppType.Builder.section(SectionType section) |
| Modifier and Type | Method and Description |
|---|---|
B |
VAppTemplate.Builder.sections(Iterable<? extends SectionType> sections) |
B |
AbstractVAppType.Builder.sections(Iterable<? extends SectionType> sections) |
| Modifier and Type | Class and Description |
|---|---|
class |
VirtualSystem |
| Modifier and Type | Field and Description |
|---|---|
protected Set<SectionType> |
InstantiationParams.sections |
protected Set<SectionType> |
CaptureVAppParams.sections |
| Modifier and Type | Method and Description |
|---|---|
Set<SectionType> |
InstantiationParams.getSections()
An
ovf:Section to configure for instantiation. |
Set<SectionType> |
CaptureVAppParams.getSections()
An
ovf:Section to configure the captured vAppTemplate. |
| Modifier and Type | Method and Description |
|---|---|
InstantiationParams.Builder |
InstantiationParams.Builder.section(SectionType section) |
B |
CaptureVAppParams.Builder.section(SectionType section) |
| Modifier and Type | Method and Description |
|---|---|
InstantiationParams.Builder |
InstantiationParams.Builder.sections(Iterable<? extends SectionType> sections) |
B |
CaptureVAppParams.Builder.sections(Iterable<? extends SectionType> sections) |
| Modifier and Type | Class and Description |
|---|---|
class |
CustomizationSection
Represents a vApp template customization settings section.
|
class |
GuestCustomizationSection
Represents a guest customization settings.
|
class |
LeaseSettingsSection
Represents the lease settings section for a vApp.
|
class |
NetworkConfigSection
Represents the network config section of a vApp.
|
class |
NetworkConnectionSection
Represents a list of network cards existing in a VM.
|
class |
RuntimeInfoSection
Runtime information for a specific vm
|
| Modifier and Type | Class and Description |
|---|---|
class |
SectionForVApp<S extends SectionType> |
class |
SectionForVAppTemplate<S extends SectionType> |
Copyright © 2009-2013 jclouds. All Rights Reserved.


#include <search.h> void insque(void *elem, void *prev); void remque(void *elem);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
insque(), remque():
The insque() function inserts the element pointed to by elem immediately after the element pointed to by prev.
If the list is linear, then the call insque(elem, NULL) can be used to insert the initial list element, and the call sets the forward and backward pointers of elem to NULL.
If the list is circular, the caller should ensure that the forward and backward pointers of the first element are initialized to point to that element, and the prev argument of the insque() call should also point to the element.
The remque() function removes the element pointed to by elem from the doubly-linked list.
struct qelem { struct qelem *q_forw; struct qelem *q_back; char q_data[1]; };
This is still what you will get if _GNU_SOURCE is defined before including <search.h>.
The location of the prototypes for these functions differs among several versions of UNIX. The above is the POSIX version. Some systems place them in <string.h>.
$ ./a.out -c a b c Traversing completed list: a b c That was a circular list
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <search.h> struct element { struct element *forward; struct element *backward; char *name; }; static struct element * new_element(void) { struct element *e; e = malloc(sizeof(struct element)); if (e == NULL) { fprintf(stderr, "malloc() failed\n"); exit(EXIT_FAILURE); } return e; } int main(int argc, char *argv[]) { struct element *first, *elem, *prev; int circular, opt, errfnd; /* The "-c" command-line option can be used to specify that the list is circular */ errfnd = 0; circular = 0; while ((opt = getopt(argc, argv, "c")) != -1) { switch (opt) { case 'c': circular = 1; break; default: errfnd = 1; break; } } if (errfnd || optind >= argc) { fprintf(stderr, "Usage: %s [-c] string...\n", argv[0]); exit(EXIT_FAILURE); } /* Create first element and place it in the linked list */ elem = new_element(); first = elem; elem->name = argv[optind]; if (circular) { elem->forward = elem; elem->backward = elem; insque(elem, elem); } else { insque(elem, NULL); } /* Add remaining command-line arguments as list elements */ while (++optind < argc) { prev = elem; elem = new_element(); elem->name = argv[optind]; insque(elem, prev); } /* Traverse the list from the start, printing element names */ printf("Traversing completed list:\n"); elem = first; do { printf(" %s\n", elem->name); elem = elem->forward; } while (elem != NULL && elem != first); if (elem == first) printf("That was a circular list\n"); exit(EXIT_SUCCESS); }


This site has one job: to tell you whether a given number is prime or not.
If you go to, for example, isthisprime.com/57, it will tell you that 57 is not a prime number.
For numbers up to 10 digits long, it uses the deterministic Miller test to determine if the number is prime, with 100% certainty. This is a remarkably clever algorithm which can decide primality in logarithmic time.
For larger numbers, it uses the probabilistic Miller-Rabin test to make a pretty good guess about whether the given number is prime. "Pretty good" in this case means "practically certain" - you're very unlikely to type in a number which the algorithm says is probably prime but which is in fact composite. However, when the algorithm says a number is composite, it's definitely composite.
For numbers up to 25 digits long, the Miller-Rabin test can give definite answers for primes up to about 25 digits long, by using a set of "witness" bases.
If I was cleverer, I'd pay more attention to the intricacies of these tests to make them run faster and be more certain, but I'm already at the edge of my understanding.
You can turn on screensaver mode by adding ?screensaver
to the end of the URL, e.g. isthisprime.com/57?screensaver. It'll automatically move on to the next number every 5 seconds.
If you would rather decide what's prime and what's not, try the Is this prime? game.


He has Bachelor in Science, Major in Computer Science (2008) and post-graduate certificate in IT Management (2010) by Devry Brazil. He also has MBA in Project and Business Management (2011) from Faculdade Ateneu and a Master in Science, Major Applied Computer Science from the University of Fortaleza (2015). Currently he is a PhD student at the University of Regina and a paper reviewer of the PMI Conferences. He has 9 years with experience in project management (PMP) and PHP development, 7 years as a teacher and 14 years in total in I.T.