Rename year directories to allow natural ordering

This commit is contained in:
2023-12-20 03:57:27 +00:00
parent 0ab1f5ad3a
commit 1f7d812b98
1895 changed files with 0 additions and 7188 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="semeru-18" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/CT255-Assignment-2.iml" filepath="$PROJECT_DIR$/CT255-Assignment-2.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,50 @@
\addtolength{\hoffset}{-2.25cm}
\addtolength{\textwidth}{4.5cm}
\addtolength{\voffset}{-3.25cm}
\addtolength{\textheight}{5cm}
\setlength{\parskip}{0pt}
\setlength{\parindent}{0in}
%----------------------------------------------------------------------------------------
% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS
%----------------------------------------------------------------------------------------
\usepackage{blindtext} % Package to generate dummy text
\usepackage{charter} % Use the Charter font
\usepackage[utf8]{inputenc} % Use UTF-8 encoding
\usepackage{microtype} % Slightly tweak font spacing for aesthetics
\usepackage[english, ngerman]{babel} % Language hyphenation and typographical rules
\usepackage{amsthm, amsmath, amssymb} % Mathematical typesetting
\usepackage{float} % Improved interface for floating objects
\usepackage[final, colorlinks = true,
linkcolor = black,
citecolor = black]{hyperref} % For hyperlinks in the PDF
\usepackage{graphicx, multicol} % Enhanced support for graphics
\usepackage{xcolor} % Driver-independent color extensions
\usepackage{marvosym, wasysym} % More symbols
\usepackage{rotating} % Rotation tools
\usepackage{censor} % Facilities for controlling restricted text
\usepackage{listings, style/lstlisting} % Environment for non-formatted code, !uses style file!
\usepackage{pseudocode} % Environment for specifying algorithms in a natural way
\usepackage{style/avm} % Environment for f-structures, !uses style file!
\usepackage{booktabs} % Enhances quality of tables
\usepackage{tikz-qtree} % Easy tree drawing tool
\tikzset{every tree node/.style={align=center,anchor=north},
level distance=2cm} % Configuration for q-trees
\usepackage{style/btree} % Configuration for b-trees and b+-trees, !uses style file!
\usepackage[backend=biber,style=numeric,
sorting=nyt]{biblatex} % Complete reimplementation of bibliographic facilities
\addbibresource{ecl.bib}
\usepackage{csquotes} % Context sensitive quotation facilities
\usepackage[yyyymmdd]{datetime} % Uses YEAR-MONTH-DAY format for dates
\renewcommand{\dateseparator}{-} % Sets dateseparator to '-'
\usepackage{fancyhdr} % Headers and footers
\pagestyle{fancy} % All pages have headers and footers
\fancyhead{}\renewcommand{\headrulewidth}{0pt} % Blank out the default header
\fancyfoot[L]{} % Custom footer text
\fancyfoot[C]{} % Custom footer text
\fancyfoot[R]{\thepage} % Custom footer text
\newcommand{\note}[1]{\marginpar{\scriptsize \textcolor{red}{#1}}} % Enables comments in red on margin
%----------------------------------------------------------------------------------------

View File

@ -0,0 +1,121 @@
\documentclass[a4paper]{article}
\input{head}
\begin{document}
%-------------------------------
% TITLE SECTION
%-------------------------------
\fancyhead[C]{}
\hrule \medskip % Upper rule
\begin{minipage}{0.295\textwidth}
\raggedright
\footnotesize
Andrew Hayes \hfill\\
21321503 \hfill\\
a.hayes18@nuigalway.ie
\end{minipage}
\begin{minipage}{0.4\textwidth}
\centering
\large
CT255 Assignment 1\\
\normalsize
GDPR\\
\end{minipage}
\begin{minipage}{0.295\textwidth}
\raggedleft
\today\hfill\\
\end{minipage}
\medskip\hrule
\bigskip
%-------------------------------
% CONTENTS
%-------------------------------
\section{Problem 1}
\subsection{What is GDPR?}
The \textbf{General Data Protection Regulation (GDPR)} is a legal regulation in EU law pertaining to the protection of data within the European Union and the European Economic Area (EEA), and the protection of this data when it is transferred out of this region. GDPR applies to any organisation that is processing the personal data of individuals who are in the EEA, regardless of the location of said organisation or the citizenship / residence status of the individuals whose data is being processed. GDPR sets out several key principles in relation to the processing of personal data:
\begin{itemize}
\item \textbf{Lawfulness -} You must identify a \textit{lawful basis} under the GDPR for the processing of personal data.
\item \textbf{Fairness \& Transparency -} You must be open \& honest with the Data Subjects about how and why their data is being processed, and you must not use this data in a way that doesn't align with these methods.
\item \textbf{Purpose Limitation -} You must clearly state your purposes for processing the personal data of Data Subjects from the start, and may only use the data for different purpose if it is either compatible with your original purpose, you get \textit{consent}, or if you have a \textit{clear basis} in law.
\item \textbf{Data Minimisation -} The personal data you process must be \textit{adequate}, \textit{relevant}, and \textit{limited} only to what is necessary.
\item \textbf{Accuracy -} Personal data should not be incorrect or misleading.
\item \textbf{Storage Limitation -} You must not keep personal data for longer than you need it.
\item \textbf{Integrity \& Confidentiality -} You must take appropriate technical \& organisational measures to ensure that the personal data of data subjects remains \textit{secure}.
\item \textbf{Accountability -} You must be able to demonstrate your compliance with GDPR.
\end{itemize}
\bigbreak
All Data Processors (i.e., anyone who is responsible for the processing of personal information) are motivated to obey GDPR by threat of strict penalties. For particularly serious GDPR breaches, a Data Processor could be fined up to €20 million, or 4\% of the firm's global turnover. For less serious breaches, the Data Processor can be fined up to €10 million, or 2\% of the firm's global turnover.
\subsection{Why was GDPR introduced? What was the motivation for this legislation?}
GDPR was introduced with the aim of enhancing the rights \& control of individuals over their personal data and to simplify data processing regulations with regards to international businesses.
\bigbreak
As the processing of the personal data of individuals increases in the modern world with the advent of modern technology, it has became necessary to update the laws governing the processing of personal data to protect the interests of data subjects in an era of unprecedented data collection, surveillance, \& processing. GDPR sets out clear \& concise principles \& rules that determine who's personal data may be processed, what information this data may consist of, when it is acceptable to process it, where this data can be processed \& relocated to, why this data may or may not be processed, and how this data processing can be undertaken.
\bigbreak
The European Parliament adopted the GDPR in April 2016 to replace the then-outdated Data Protection Directive, which was first enacted in 1995.
There were 2 main issues with the Data Protection Directive that made it necessary to replace it:
\begin{enumerate}
\item Under EU law, a ``Directive'' is less strict than a ``Regulation''.
A Directive allows the EU member states to adapt \& change the law to fit the needs of their citizens, while a Regulation does not allow this.
A Regulation forces the member states to adopt it, and does not allow them to adapt or change it at all.
\item The Data Protection Directive was too outdated for the modern world.
It did not address how data is collected, stored, or transferred in the digital world, and thus largely failed to regulate digital data processing.
\end{enumerate}
\bigskip
%------------------------------------------------
\section{Problem 2}
This company needs to be extremely careful with their GDPR compliance, as they are handling some extremely sensitive personal information.
\newline\newline
With regards to the GDPR key principle of \textbf{Lawfulness}, I think that this website is in the clear.
Since the users are uploading their own data of their own volition, this gives the website a clear lawful basis for data processing - they have the \textit{consent} of the data subjects for the processing of their data.
\newline\newline
I do, however, have some concerns about the compliance of the company with GDPR key principle \textbf{Fairness \& Transparency}. The company is quite vague about how they process the personal data of the users, how the data is stored, etc.
There is no mention of any kind of Data Protection Notice that informs the user of the identity \& contact details of the Data Controller, the contact details of the Data Protection officer, the details of any data transfer out of of the EEA or the safeguards in place, the data retention period, or the individual's rights.
The only information that the Data Subjects really have is the purpose of the processing and (at least some of) the recipients of the data.
It's possible that other people are in receipt of the users' personal data as well, but there is no mention of this.
\bigbreak
The company should be in the clear with regards to \textbf{Purpose Limitation}, assuming that they are being fully open \& honest about their purposes for processing the data, and stick to these purposes, but if they are not doing this, then that is a massive issue.
\newline\newline
The principle of \textbf{Data Minimisation} is a bit more of a grey area for this website.
It's hard to say what data is and isn't adequate \& relevant to the purpose of "keeping in touch".
Personally, I would be of the opinion that absolutely none of the data mentioned is relevant for the purposes of "keeping in touch", but it is plausible that some people would feel otherwise.
It could be problematic for the company that they allow the users to upload pretty much whatever they want, as the company may end up in possession of a lot of irrelevant data that the users uploaded.
The company needs to be extremely careful with receiving data that they didn't expect to receive, which may or may not be relevant to the purposes of the company.
\newline\newline
The principle of \textbf{Accuracy} is another potentially problematic one for this company.
The company must take all reasonable steps to ensure that the personal data that they hold is not incorrect or misleading as to any matter of fact.
It's not unlikely that some, if not many, of the users of the website will ``exaggerate'' (or just make up) positive aspects of their life after university, their salary, etc.
There also doesn't seem to be any protocol to verify that the users are who they say they are, so anyone could be uploading the personal data, fictitious or otherwise, of anyone else, and this data could be viewed by anyone in the world, so long as they claimed to be an alumni of a particular course.
This is a problem for the company, as they have the responsibility to ensure that the data is accurate, although this may be considered to be something that the company cannot reasonably be expected to regulate / control.
\newline\newline
The company does not seem to comply with the principle of \textbf{Storage Limitation} at all.
There is no mention of data retention period, or how the users might be able to learn their data retention periods.
\newline\newline
Similarly, the company doesn't seem to comply with \textbf{Accountability \& Governance} at all either.
There is no attempt to provide an assurance of GDPR compliance, or to explain why the data is held, when it will be deleted, and who may gain access to it.
\newline\newline
There is no mention of any attempt to comply with \textbf{Integrity \& Confidentiality} either.
There is no mention of any security measure such as encryption, nor do they mention any other technical measures that they might use to process the data securely.
\bigskip
\section{References}
\begin{enumerate}
\item Schukat, M. (2022-09-09). \textit{CT255 Lecture Slides - GDPR.} Blackboard.
\item Wolford, B. \textit{What is GDPR, the EU's new data protection law?} Proton. https://gdpr.eu/what-is-gdpr/
\item Sivula, A. \textit{GDPR: What Happens If You Don't Comply}. AMD Solicitors. https://amdsolicitors.com/gdpr-what-happens-if-you-dont-comply/
\item Rossow, A. \textit{The Birth of GDPR: What Is It And What You Need To Know}. Forbes\\ https://www.forbes.com/sites/andrewrossow/2018/05/25/the-birth-of-gdpr-what-is-it-and-what-you-need-to-know/?sh=62b80a5a55e5
\end{enumerate}
%------------------------------------------------
\end{document}

View File

@ -0,0 +1,97 @@
//package ct255;
import java.util.Random;
public class CT255_HashFunction1 {
public static void main(String[] args) {
int res = 0;
if (args != null && args.length > 0) { // Check for <input> value
res = hashF1(args[0]); // call hash function with <input>
if (res < 0) { // Error
System.out.println("Error: <input> must be 1 to 64 characters long.");
}
else {
System.out.println("input = " + args[0] + " : Hash = " + res);
System.out.println("Start searching for collisions");
int collisionCount = 0; // variable to count the number of collisions found
// string containing all possible ASCII characters (exclusding control characters such as [NULL])
String allChars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
for (int i = 0; i < 100000; i++) { // checking one million randomly generated strings for hash collisions
StringBuilder str = new StringBuilder(); // creating a new StringBuilder to build char by char
// generating 64 random characters & appending them to str
for (int j = 0; j < 64; j++) {
char c = allChars.charAt(new Random().nextInt(allChars.length())); // selecting a random character from allChars
str.append(c); // appending the randomly selected character to str
}
// hashing str & checking if the hash matches res
if (hashF1(str.toString()) == res) {
collisionCount++; // iterating collisionCount if collision found
System.out.println(str); // printing the String that generated the collision
}
}
// printing the number of collisions found
System.out.printf("%d hash collisions found!", collisionCount);
}
}
else { // No <input>
System.out.println("Use: CT255_HashFunction1 <Input>");
}
}
private static int hashF1(String s){
int ret = -1, i;
int[] hashA = new int[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // i extended this array by 6 indices to make code more robust
// essentially, the extent of my improvements was just increasing the size of the hashA array
String filler, sIn;
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
if ((s.length() > 64) || (s.length() < 1)) { // String does not have required length
ret = -1;
}
else {
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
sIn = sIn.substring(0, 64); // // Limit string to first 64 characters
// System.out.println(sIn); // FYI
for (i = 0; i < sIn.length(); i++){
char byPos = sIn.charAt(i); // get ith character
hashA[0] += (byPos * 17); // Note: A += B means A = A + B
hashA[1] += (byPos * 31);
hashA[2] += (byPos * 101);
hashA[3] += (byPos * 79);
hashA[4] += byPos * 83;
hashA[5] += byPos * 89;
hashA[6] += byPos * 103;
hashA[7] += byPos * 107;
hashA[8] += byPos * 109;
hashA[9] += byPos * 113;
}
hashA[0] %= 255; // % is the modulus operation, i.e. division with rest
hashA[1] %= 255;
hashA[2] %= 255;
hashA[3] %= 255;
hashA[4] %= 255;
hashA[5] %= 255;
hashA[6] %= 255;
hashA[7] %= 255;
hashA[8] %= 255;
hashA[9] %= 255;
ret = hashA[0] + (hashA[1] * 256) + (hashA[2] * 256 * 256) + (hashA[3] * 256 * 256 * 256) + (hashA[4] * 256*256*256*256) + (hashA[5] * 256*256*256*256*256) + (hashA[6] * 256*236*256*256*256*256)
+ (hashA[6] * 256*256*256*256*256*256) + (hashA[7] * 256*256*256*256*256*256*256) + (hashA[8] * 256*256*256*256*256*256*256*256) + (hashA[9] * 256*256*256*256*256*256*256*256*256);
if (ret < 0) ret *= -1;
}
return ret;
}
}

View File

@ -0,0 +1,97 @@
//package ct255;
import java.util.Random;
public class CT255_HashFunction1 {
public static void main(String[] args) {
int res = 0;
if (args != null && args.length > 0) { // Check for <input> value
res = hashF1(args[0]); // call hash function with <input>
if (res < 0) { // Error
System.out.println("Error: <input> must be 1 to 64 characters long.");
}
else {
System.out.println("input = " + args[0] + " : Hash = " + res);
System.out.println("Start searching for collisions");
int collisionCount = 0; // variable to count the number of collisions found
// string containing all possible ASCII characters (exclusding control characters such as [NULL])
String allChars = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
for (int i = 0; i < 100000; i++) { // checking one million randomly generated strings for hash collisions
StringBuilder str = new StringBuilder(); // creating a new StringBuilder to build char by char
// generating 64 random characters & appending them to str
for (int j = 0; j < 64; j++) {
char c = allChars.charAt(new Random().nextInt(allChars.length())); // selecting a random character from allChars
str.append(c); // appending the randomly selected character to str
}
// hashing str & checking if the hash matches res
if (hashF1(str.toString()) == res) {
collisionCount++; // iterating collisionCount if collision found
System.out.println(str); // printing the String that generated the collision
}
}
// printing the number of collisions found
System.out.printf("%d hash collisions found!", collisionCount);
}
}
else { // No <input>
System.out.println("Use: CT255_HashFunction1 <Input>");
}
}
private static int hashF1(String s){
int ret = -1, i;
int[] hashA = new int[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // i extended this array by 6 indices to make code more robust
// essentially, the extent of my improvements was just increasing the size of the hashA array
String filler, sIn;
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
if ((s.length() > 64) || (s.length() < 1)) { // String does not have required length
ret = -1;
}
else {
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
sIn = sIn.substring(0, 64); // // Limit string to first 64 characters
// System.out.println(sIn); // FYI
for (i = 0; i < sIn.length(); i++){
char byPos = sIn.charAt(i); // get ith character
hashA[0] += (byPos * 17); // Note: A += B means A = A + B
hashA[1] += (byPos * 31);
hashA[2] += (byPos * 101);
hashA[3] += (byPos * 79);
hashA[4] += byPos * 83;
hashA[5] += byPos * 89;
hashA[6] += byPos * 103;
hashA[7] += byPos * 107;
hashA[8] += byPos * 109;
hashA[9] += byPos * 113;
}
hashA[0] %= 255; // % is the modulus operation, i.e. division with rest
hashA[1] %= 255;
hashA[2] %= 255;
hashA[3] %= 255;
hashA[4] %= 255;
hashA[5] %= 255;
hashA[6] %= 255;
hashA[7] %= 255;
hashA[8] %= 255;
hashA[9] %= 255;
ret = hashA[0] + (hashA[1] * 256) + (hashA[2] * 256 * 256) + (hashA[3] * 256 * 256 * 256) + (hashA[4] * 256*256*256*256) + (hashA[5] * 256*256*256*256*256) + (hashA[6] * 256*236*256*256*256*256)
+ (hashA[6] * 256*256*256*256*256*256) + (hashA[7] * 256*256*256*256*256*256*256) + (hashA[8] * 256*256*256*256*256*256*256*256) + (hashA[9] * 256*256*256*256*256*256*256*256*256);
if (ret < 0) ret *= -1;
}
return ret;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="semeru-18" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/CT255-Assignment-2.iml" filepath="$PROJECT_DIR$/CT255-Assignment-2.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,123 @@
import java.util.HashMap;
/* CT255 Assignment 2
* This class provides functionality to build rainbow tables (with a different reduction function per round) for 8 character long strings, which
consist of the symbols "a .. z", "A .. Z", "0 .. 9", "!" and "#" (64 symbols in total).
Properly used, it creates the following value pairs (start value - end value) after 10,000 iterations of hashFunction() and reductionFunction():
start value - end value
Kermit12 lsXcRAuN
Modulus! L2rEsY8h
Pigtail1 R0NoLf0w
GalwayNo 9PZjwF5c
Trumpets !oeHRZpK
HelloPat dkMPG7!U
pinky##! eDx58HRq
01!19!56 vJ90ePjV
aaaaaaaa rLtVvpQS
aaaaaaaa klQ6IeQJ
*
* @author Michael Schukat
* @version 1.0
*/
public class RainbowTable
{
public static void main(String[] args) {
long res = 0;
// String array of the known passwords
String[] passwords = {"Kermit12", "Modulus!", "Pigtail1", "GalwayNo", "Trumpets", "HelloPat", "pinky##!", "01!19!56", "aaaaaaaa", "aaaaaaaa"};
HashMap<String, String> rainbowTable = new HashMap<>(); // declaring a HashTable that i'll use to store the password : hash pairs
// looping through the passwords array
for (String start : passwords) {
if (start.length() != 8) {
System.out.println("Input " + start + " must be 8 characters long - Exit");
}
else {
String hash = start; // declaring a String hash that will hold the final reduced hash of a given password
// hashing & reducing the start String 10000 times.
for (int i = 0; i < 10000; i++) {
hash = reductionFunction((hashFunction(hash)), i);
}
// adding the password & its hash value to the rainbowTable HashMap
rainbowTable.put(start, hash);
}
}
// printing out the contents of the rainbowTable
System.out.println(rainbowTable);
// chain lookup section
// long array of the 4 hashes to be searched for
long[] hashes = {895210601874431214L, 750105908431234638L, 111111111115664932L, 977984261343652499L};
// for each loop that loops through each hash in the array of hashes
for (long hash : hashes) {
// looping 10000 times to search for the password - this will function as our max number of iterations, as 10000 iterations should just take use back to where we started.
for (int i = 0; i < 10000; i++) {
// reducing the hash
String str = reductionFunction(hash, i);
System.out.println(hash + " : " + str);
// checking if the reduced hash is a value (final plaintext) in the rainbowTable HashMap
if (rainbowTable.containsValue(str)) {
System.out.println("Found password " + str + " for hash value " + hash); // printing the found password
break; // breaking out of the for loop
}
else {
hash = hashFunction(str); // hashing str before continuing the for loop
}
}
}
}
private static long hashFunction(String s){
long ret = 0;
int i;
long[] hashA = new long[]{1, 1, 1, 1};
String filler, sIn;
int DIV = 65536;
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
sIn = sIn.substring(0, 64); // Limit string to first 64 characters
for (i = 0; i < sIn.length(); i++) {
char byPos = sIn.charAt(i); // get i'th character
hashA[0] += (byPos * 17111); // Note: A += B means A = A + B
hashA[1] += (hashA[0] + byPos * 31349);
hashA[2] += (hashA[1] - byPos * 101302);
hashA[3] += (byPos * 79001);
}
ret = (hashA[0] + hashA[2]) + (hashA[1] * hashA[3]);
if (ret < 0) ret *= -1;
return ret;
}
private static String reductionFunction(long val, int round) { // Note that for the first function call "round" has to be 0,
String car, out; // and has to be incremented by one with every subsequent call.
int i; // I.e. "round" created variations of the reduction function.
char dat;
car = new String("0123456789ABCDEFGHIJKLMNOPQRSTUNVXYZabcdefghijklmnopqrstuvwxyz!#");
out = new String("");
for (i = 0; i < 8; i++) {
val -= round;
dat = (char) (val % 63);
val = val / 83;
out = out + car.charAt(dat);
}
return out;
}
}

View File

@ -0,0 +1,49 @@
\addtolength{\hoffset}{-2.25cm}
\addtolength{\textwidth}{4.5cm}
\addtolength{\voffset}{-3.25cm}
\addtolength{\textheight}{5cm}
\setlength{\parskip}{0pt}
\setlength{\parindent}{0in}
%----------------------------------------------------------------------------------------
% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS
%----------------------------------------------------------------------------------------
\usepackage{blindtext} % Package to generate dummy text
\usepackage{charter} % Use the Charter font
\usepackage[utf8]{inputenc} % Use UTF-8 encoding
\usepackage{microtype} % Slightly tweak font spacing for aesthetics
\usepackage[english, ngerman]{babel} % Language hyphenation and typographical rules
\usepackage{amsthm, amsmath, amssymb} % Mathematical typesetting
\usepackage{float} % Improved interface for floating objects
\usepackage[final, colorlinks = true,
linkcolor = black,
citecolor = black]{hyperref} % For hyperlinks in the PDF
\usepackage{graphicx, multicol} % Enhanced support for graphics
\usepackage{xcolor} % Driver-independent color extensions
\usepackage{marvosym, wasysym} % More symbols
\usepackage{rotating} % Rotation tools
\usepackage{censor} % Facilities for controlling restricted text
\usepackage{listings, style/lstlisting} % Environment for non-formatted code, !uses style file!
\usepackage{pseudocode} % Environment for specifying algorithms in a natural way
\usepackage{style/avm} % Environment for f-structures, !uses style file!
\usepackage{booktabs} % Enhances quality of tables
\usepackage{tikz-qtree} % Easy tree drawing tool
\tikzset{every tree node/.style={align=center,anchor=north},
level distance=2cm} % Configuration for q-trees
\usepackage{style/btree} % Configuration for b-trees and b+-trees, !uses style file!
\usepackage[backend=biber,style=numeric,
sorting=nyt]{biblatex} % Complete reimplementation of bibliographic facilities
\addbibresource{ecl.bib}
\usepackage{csquotes} % Context sensitive quotation facilities
\usepackage[yyyymmdd]{datetime} % Uses YEAR-MONTH-DAY format for dates
\renewcommand{\dateseparator}{-} % Sets dateseparator to '-'
\usepackage{fancyhdr} % Headers and footers
\pagestyle{fancy} % All pages have headers and footers
\fancyhead{}\renewcommand{\headrulewidth}{0pt} % Blank out the default header
\fancyfoot[L]{} % Custom footer text
\fancyfoot[C]{} % Custom footer text
\fancyfoot[R]{\thepage} % Custom footer text
\newcommand{\note}[1]{\marginpar{\scriptsize \textcolor{red}{#1}}} % Enables comments in red on margin
%----------------------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -0,0 +1,281 @@
\documentclass[a4paper]{article}
\input{head}
\begin{document}
%-------------------------------
% TITLE SECTION
%-------------------------------
\fancyhead[C]{}
\hrule \medskip % Upper rule
\begin{minipage}{0.295\textwidth}
\raggedright
\footnotesize
Andrew Hayes \hfill\\
21321503 \hfill\\
a.hayes18@nuigalway.ie
\end{minipage}
\begin{minipage}{0.4\textwidth}
\centering
\large
CT255 Assignment 2\\
\normalsize
Rainbow Tables\\
\end{minipage}
\begin{minipage}{0.295\textwidth}
\raggedleft
\today\hfill\\
\end{minipage}
\medskip\hrule
\bigskip
%-------------------------------
% CONTENTS
%-------------------------------
\section{Problem 1}
\subsection{Code}
\begin{lstlisting}[language=Java]
import java.util.HashMap;
/* CT255 Assignment 2
* This class provides functionality to build rainbow tables (with a different reduction function per round) for 8 character long strings, which
consist of the symbols "a .. z", "A .. Z", "0 .. 9", "!" and "#" (64 symbols in total).
Properly used, it creates the following value pairs (start value - end value) after 10,000 iterations of hashFunction() and reductionFunction():
start value - end value
Kermit12 lsXcRAuN
Modulus! L2rEsY8h
Pigtail1 R0NoLf0w
GalwayNo 9PZjwF5c
Trumpets !oeHRZpK
HelloPat dkMPG7!U
pinky##! eDx58HRq
01!19!56 vJ90ePjV
aaaaaaaa rLtVvpQS
aaaaaaaa klQ6IeQJ
*
* @author Michael Schukat
* @version 1.0
*/
public class RainbowTable
{
public static void main(String[] args) {
long res = 0;
// String array of the known passwords
String[] passwords = {"Kermit12", "Modulus!", "Pigtail1", "GalwayNo", "Trumpets", "HelloPat", "pinky##!", "01!19!56", "aaaaaaaa", "aaaaaaaa"};
HashMap<String, String> rainbowTable = new HashMap<>(); // declaring a HashTable that i'll use to store the password : hash pairs
// looping through the passwords array
for (String start : passwords) {
if (start.length() != 8) {
System.out.println("Input " + start + " must be 8 characters long - Exit");
}
else {
String hash = start; // declaring a String hash that will hold the final reduced hash of a given password
// hashing & reducing the start String 10000 times.
for (int i = 0; i < 10000; i++) {
hash = reductionFunction((hashFunction(hash)), i);
}
// adding the password & its hash value to the rainbowTable HashMap
rainbowTable.put(start, hash);
}
}
// printing out the contents of the rainbowTable
System.out.println(rainbowTable);
}
private static long hashFunction(String s){
long ret = 0;
int i;
long[] hashA = new long[]{1, 1, 1, 1};
String filler, sIn;
int DIV = 65536;
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
sIn = sIn.substring(0, 64); // // Limit string to first 64 characters
for (i = 0; i < sIn.length(); i++) {
char byPos = sIn.charAt(i); // get i'th character
hashA[0] += (byPos * 17111); // Note: A += B means A = A + B
hashA[1] += (hashA[0] + byPos * 31349);
hashA[2] += (hashA[1] - byPos * 101302);
hashA[3] += (byPos * 79001);
}
ret = (hashA[0] + hashA[2]) + (hashA[1] * hashA[3]);
if (ret < 0) ret *= -1;
return ret;
}
private static String reductionFunction(long val, int round) { // Note that for the first function call "round" has to be 0,
String car, out; // and has to be incremented by one with every subsequent call.
int i; // I.e. "round" created variations of the reduction function.
char dat;
car = new String("0123456789ABCDEFGHIJKLMNOPQRSTUNVXYZabcdefghijklmnopqrstuvwxyz!#");
out = new String("");
for (i = 0; i < 8; i++) {
val -= round;
dat = (char) (val % 63);
val = val / 83;
out = out + car.charAt(dat);
}
return out;
}
}
\end{lstlisting}
\subsection{Output}
\includegraphics[width = 16cm]{image.png}
\bigskip
%------------------------------------------------
\section{Problem 2}
\subsection{Code}
\begin{lstlisting}[language=java]
import java.util.HashMap;
/* CT255 Assignment 2
* This class provides functionality to build rainbow tables (with a different reduction function per round) for 8 character long strings, which
consist of the symbols "a .. z", "A .. Z", "0 .. 9", "!" and "#" (64 symbols in total).
Properly used, it creates the following value pairs (start value - end value) after 10,000 iterations of hashFunction() and reductionFunction():
start value - end value
Kermit12 lsXcRAuN
Modulus! L2rEsY8h
Pigtail1 R0NoLf0w
GalwayNo 9PZjwF5c
Trumpets !oeHRZpK
HelloPat dkMPG7!U
pinky##! eDx58HRq
01!19!56 vJ90ePjV
aaaaaaaa rLtVvpQS
aaaaaaaa klQ6IeQJ
*
* @author Michael Schukat
* @version 1.0
*/
public class RainbowTable
{
public static void main(String[] args) {
long res = 0;
// String array of the known passwords
String[] passwords = {"Kermit12", "Modulus!", "Pigtail1", "GalwayNo", "Trumpets", "HelloPat", "pinky##!", "01!19!56", "aaaaaaaa", "aaaaaaaa"};
HashMap<String, String> rainbowTable = new HashMap<>(); // declaring a HashTable that i'll use to store the password : hash pairs
// looping through the passwords array
for (String start : passwords) {
if (start.length() != 8) {
System.out.println("Input " + start + " must be 8 characters long - Exit");
}
else {
String hash = start; // declaring a String hash that will hold the final reduced hash of a given password
// hashing & reducing the start String 10000 times.
for (int i = 0; i < 10000; i++) {
hash = reductionFunction((hashFunction(hash)), i);
}
// adding the password & its hash value to the rainbowTable HashMap
rainbowTable.put(start, hash);
}
}
// printing out the contents of the rainbowTable
System.out.println(rainbowTable);
// chain lookup section
// long array of the 4 hashes to be searched for
long[] hashes = {895210601874431214L, 750105908431234638L, 111111111115664932L, 977984261343652499L};
// for each loop that loops through each hash in the array of hashes
for (long hash : hashes) {
// looping 10000 times to search for the password - this will function as our max number of iterations, as 10000 iterations should just take use back to where we started.
for (int i = 0; i < 10000; i++) {
// reducing the hash
String str = reductionFunction(hash, i);
// checking if the reduced hash is a key (password) in the rainbowTable HashMap
if (rainbowTable.containsValue(str)) {
System.out.println("Found password " + str + " for hash value " + hash); // printing the found password
break; // breaking out of the for loop
}
else {
hash = hashFunction(str); // hashing str before continuing the for loop
}
}
}
}
private static long hashFunction(String s){
long ret = 0;
int i;
long[] hashA = new long[]{1, 1, 1, 1};
String filler, sIn;
int DIV = 65536;
filler = new String("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH");
sIn = s + filler; // Add characters, now have "<input>HABCDEF..."
sIn = sIn.substring(0, 64); // // Limit string to first 64 characters
for (i = 0; i < sIn.length(); i++) {
char byPos = sIn.charAt(i); // get i'th character
hashA[0] += (byPos * 17111); // Note: A += B means A = A + B
hashA[1] += (hashA[0] + byPos * 31349);
hashA[2] += (hashA[1] - byPos * 101302);
hashA[3] += (byPos * 79001);
}
ret = (hashA[0] + hashA[2]) + (hashA[1] * hashA[3]);
if (ret < 0) ret *= -1;
return ret;
}
private static String reductionFunction(long val, int round) { // Note that for the first function call "round" has to be 0,
String car, out; // and has to be incremented by one with every subsequent call.
int i; // I.e. "round" created variations of the reduction function.
char dat;
car = new String("0123456789ABCDEFGHIJKLMNOPQRSTUNVXYZabcdefghijklmnopqrstuvwxyz!#");
out = new String("");
for (i = 0; i < 8; i++) {
val -= round;
dat = (char) (val % 63);
val = val / 83;
out = out + car.charAt(dat);
}
return out;
}
}
\end{lstlisting}
\subsection{Output}
I couldn't actually find a password match with the above code, and I'm not sure why. My current guess would be that the reduction function wasn't being called properly, as everything else \textit{seemed} to be working as expected. I didn't call the reduction more than 10,000 times as that would theoretically just lead me back to the same place in the chain. I think that my problem is with the passing of the integer \verb|i| to the reduction function, as I think that I correctly implemented the rest of the steps for performing a chain lookup - I input a hash value, reduce it, check if the reduced form is in the list of final plaintexts (the ``Values'' in the HashMap), and if so break out of the loop (but this never occurs), assigning the relevant ``Key'' from the HashMap as the original plaintext password that produced the original input hash. Otherwise, I continue until I'm back at the same place in the chain after the 10,000\textsuperscript{th} iteration, where the code gives up.
\bigskip
\includegraphics[width = 16cm]{image.png}
\end{document}

View File

@ -0,0 +1,165 @@
% avm.sty -- for attribute-value matrices -- mar 29, 1992; rev. dec 6, 1993
% (c) 1992 christopher manning (manning@csli.stanford.edu) -- see avm.doc.tex
\newif\ifavmactive\newif\ifavmsorted\newif\ifavmlabeled
\newif\ifavmcenter\newif\ifavmbottom
\newif\ifavmbottomright\newif\ifavmtopleft\newif\ifavmtopright
\newdimen\avmdimen
\newbox\avmboxone\newbox\avmboxthree
\def\avmoptions#1{\avmactivefalse\avmsortedfalse\avmlabeledfalse
\avmcenterfalse\avmbottomfalse
\avmbottomrightfalse\avmtopleftfalse\avmtoprightfalse
\def\more{#1}\ifx\more\empty\else\avmjoptions#1,\@nil\fi}
\def\avmjoptions#1,#2\@nil{\def\more{#2}\csname avm#1true\endcsname
\ifx\more\empty\else\avmjoptions#2\@nil\fi}
\def\avmfont#1{\def\avmjfont{#1}}
\def\avmjfont{}
\def\avmvalfont#1{\def\avmjvalfont{#1}}
\def\avmjvalfont{}
\def\avmsortfont#1{\def\avmjsortfont{#1}}
\def\avmjsortfont{}
\def\avmhskip#1{\def\avmjhskip{#1}}
\def\avmjhskip{1em}
\def\avmbskip#1{\def\avmjbskip{#1}}
\def\avmjbskip{0em}
\def\avmvskip#1{\def\avmjvskip{#1}}
\def\avmjvskip{0.385ex}%was .3875
\def\avmjprolog#1{$\mskip-\thinmuskip
\left#1\hskip\avmjbskip\vcenter\bgroup\vskip\avmjvskip
\ialign\bgroup\avmjfont
\strut ##\unskip\hfil
&&\hskip\avmjhskip\avmjvalfont ##\unskip\hfil\cr}
\def\avmjpostlog#1{\crcr\egroup\vskip\avmjvskip\egroup
\hskip\avmjbskip\right#1\mskip-\thinmuskip$\ignorespaces}
\def\avmjcatcode{\let\lparen=(\let\rparen=)\catcode`\[=13\catcode`\]=13
\catcode`\<=13\catcode`\@=13\catcode`\(=13\catcode`\)=13
\catcode`\>=13\catcode`\|=13}
{\avmjcatcode % new group: redefine above catcodes as active
\gdef\specialavm{\avmjcatcode
\def({\avmjprolog\lparen}%
\def){\avmjpostlog\rparen}%
\def<{\avmjprolog\langle}%
\def>{\avmjpostlog\rangle}%
\ifavmsorted
\def[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox2=\hbox
\bgroup\avmjprolog\lbrack}%
\def]{\avmjpostlog\rbrack\egroup\avmjsort}%
\else\ifavmlabeled
\def[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
\def]{\avmjpostlog]\egroup\node{\more}{\box2}}%
\else
\def[{\avmjprolog\lbrack}%
\def]{\avmjpostlog\rbrack}%
\fi\fi
%
\def\<{$\langle$}\def\>{$\rangle$}%
\def\({\lparen}\def\){\rparen}%
\def\[{\lbrack}\def\]{\rbrack}%
\def|{$\,\vert\,$}%
\def@##1{\avmbox{##1}}%
} % end defn of \specialavm
} % restore active catcodes
\long\def\avm{\begingroup
\ifavmactive\specialavm
\else
\def\({\avmjprolog(}%
\def\){\avmjpostlog)}%
\def\<{\avmjprolog\langle}%
\def\>{\avmjpostlog\rangle}%
%
\ifavmsorted
\def\[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox
2=\hbox\bgroup\avmjprolog[}%
\def\]{\avmjpostlog]\egroup\avmjsort}%
\else\ifavmlabeled
\def\[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
\def\]{\avmjpostlog]\egroup\node{\more}{\box2}}%
\else
\def\[{\avmjprolog[}%
\def\]{\avmjpostlog]}%
\fi\fi
%
\def\|{$\,\vert\,$}%
\def\@##1{\avmbox{##1}}%
\fi % end not active
%
\ifx\LaTeX\undefined\def\\{\cr}% running under TeX
\else \def\\{\@tabularcr}% Leverage off LaTeX's \\*[dimen] options
\fi
\def\!{\node}%
\long\def\avmjsort{\dimen2=\ht2\advance\dimen2 by -.25\baselineskip
\global\dimen\avmdimen=\wd\avmboxthree
\ifavmtopleft \raise\dimen2\llap{\box\avmboxthree}\box2%
\else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
\else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
\else \lower\dimen2\llap{\box\avmboxthree}\box2%
\fi\fi\fi}%
\long\def\sort##1##2{\setbox2=\hbox{##2}\setbox
\avmboxthree=\hbox{\avmjsortfont##1\/}\dimen2=\ht2
\advance\dimen2 by -.25\baselineskip
\ifavmtopleft \raise\dimen2\box\avmboxthree\box2%
\else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
\else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
\else \lower\dimen2\box\avmboxthree\box2%
\fi\fi\fi}%
\long\def\osort##1##2{\setbox2=\hbox{##2}\setbox
\avmboxthree=\hbox{\avmjsortfont ##1\/}\avmjsort}%
\def\avml{\avmjprolog.}%
\def\avmr{\avmjpostlog.}%
\def\avmb##1{\node{##1}{\lbrack\;\rbrack}}%
\def\avmd##1{\node{##1}{---}}%
\def\q##1{\ifx ##1\{$\lbrace$\else
\ifx ##1\}$\rbrace$\else
\ifx ##1<$\langle$\else
\ifx ##1>$\rangle$\fi \fi \fi \fi}%
\def\{{\avmjprolog\lbrace}%
\def\}{\avmjpostlog\rbrace}%
\def\;{\hskip\avmjhskip}%
\def\avmspan##1{\multispan2\strut ##1\expandafter\hfil}%
\avmjfont
\openup\avmjvskip
\setbox\avmboxone=\hbox\bgroup\ignorespaces
} % end defn of \avm
\def\endavm{\egroup\ifvmode\leavevmode\fi % this if is useful!
\ifavmsorted\null\hskip\dimen\avmdimen\fi
\ifavmcenter
\box\avmboxone
\else \ifavmbottom
\lower.575\baselineskip\hbox{\vbox{\box\avmboxone\null}}%
\else
% the next bit is ripped off from Emma's \evnup in lingmacros.sty
\dimen2=\ht\avmboxone\advance\dimen2 by -.725\baselineskip
\lower\dimen2\box\avmboxone
\fi \fi \endgroup}
% based on TeXbook exercise 21.3
\def\avmbox#1{\setbox2=\hbox{$\scriptstyle #1$}\lower.2ex\vbox{\hrule
\hbox{\vrule\kern1.25pt
\vbox{\kern1.25pt\box2\kern1.25pt}\kern1.25pt\vrule}\hrule}}
% ============ COSTOM CONFIGURATION =============
\avmfont{\sc}
\avmoptions{sorted,active}
\avmvalfont{\rm}
\avmsortfont{\scriptsize\it}
% ===============================================

View File

@ -0,0 +1,131 @@
%% Last Modified: Thu Oct 18 18:26:25 2007.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{style/btree}
\typeout{Document Style `weiw_BTree - Support drawing B+-Tree (ver 0.999)}
\RequirePackage{tikz}
\RequirePackage{ifthen}
% use libraries
\usetikzlibrary{arrows,shapes,decorations,matrix}
%% global declaration
\tikzstyle{btreeptr} = [draw, semithick, minimum height=2em]
\tikzstyle{btreeval} = [draw, semithick, minimum size=2em]
\tikzstyle{btreevale} = [draw,semithick, minimum size=2em]
\tikzstyle{btlink} = [draw, semithick, ->, >=triangle 45]
%% macro
%% helper macros
\newcommand{\suppressemptystr}[1]{% leave blank for entries in leaf nodes
\ifthenelse{\equal{#1}{}}%
{%
\relax%
}%
% Else
{%
#1\textsuperscript{*}%
}%
}%
\newcommand{\xyshift}[3]{% help to place the nodes
\begin{scope}[xshift=#1, yshift=#2]
#3
\end{scope}%
}
%% Common btree macros
\newcommand{\btreelink}[2]{% #1: src node; #2: dest node;
\draw[btlink] ([yshift=3pt] #1.south) -- (#2-b.north);
}
\newcommand{\btreelinknorth}[2]{% #1: src node; #2: dest node;
\draw[btlink] ([yshift=3pt] #1.south) -- (#2.north);
}
\newcommand{\btreetriangle}[2]{% #1: node name; #2 text inside
\node[anchor=north, regular polygon, regular polygon sides=3, draw] (#1) {#2};
}
%%======================================================================
%% btree with capacity = 4
\newcommand{\btreeinodefour}[5]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \& \node[btreeval] (#1-c) {#4}; \&
\node[btreeptr] (#1-4) {\vphantom{1}}; \& \node[btreeval] (#1-d) {#5}; \&
\node[btreeptr] (#1-5) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodefour}[5]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \&
\node[btreevale] (#1-c) {\suppressemptystr{#4}}; \&
\node[btreevale] (#1-d) {\suppressemptystr{#5}}; \\
};
}
%%======================================================================
%% btree with capacity = 3
\newcommand{\btreeinodethree}[4]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \& \node[btreeval] (#1-c) {#4}; \&
\node[btreeptr] (#1-4) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodethree}[4]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \&
\node[btreevale] (#1-c) {\suppressemptystr{#4}}; \\
};
}
%%======================================================================
%% btree with capacity = 2
\newcommand{\btreeinodetwo}[4]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodetwo}[3]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \\
};
}
%%======================================================================
%% simple example
% \begin{center}
% \scalebox{0.7}{
% \begin{tikzpicture}
% %
% \btreeinodefour{root}{13}{17}{24}{30};
% \xyshift{-40mm}{-20mm}{\btreelnodefour{n1}{2}{3}{5}{7}}
% \xyshift{-0mm}{-20mm}{\btreelnodefour{n2}{14}{16}{}{}}
% \xyshift{40mm}{-20mm}{\btreelnodefour{n3}{19}{20}{22}{}}
% \xyshift{80mm}{-20mm}{\btreelnodefour{n4}{24}{27}{29}{}}
% \xyshift{120mm}{-20mm}{\btreelnodefour{n5}{33}{34}{38}{39}}
% %
% \foreach \x in {1,2,...,5} { \btreelink{root-\x}{n\x} }
% \end{tikzpicture}
% }
% \end{center}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,38 @@
% Source: ss17_wissschreib (Eva)
\lstset{
basicstyle=\ttfamily\scriptsize\mdseries,
keywordstyle=\bfseries\color[rgb]{0.171875, 0.242188, 0.3125},
identifierstyle=,
commentstyle=\color[rgb]{0.257813, 0.15625, 0},
stringstyle=\itshape\color[rgb]{0.0195313, 0.195313, 0.0117188},
numbers=left,
numberstyle=\tiny,
stepnumber=1,
breaklines=true,
frame=none,
showstringspaces=false,
tabsize=4,
backgroundcolor=\color[rgb]{0.98,0.98,0.98},
captionpos=b,
float=htbp,
language=Python,
xleftmargin=15pt,
xrightmargin=15pt
}
%(deutsche) Sonderzeichen
\lstset{literate=%
{Ä}{{\"A}}1
{Ö}{{\"O}}1
{Ü}{{\"U}}1
{ä}{{\"a}}1
{ö}{{\"o}}1
{ü}{{\"u}}1
{ß}{{\ss}}1
}
%Verwendung im Text:
%-> \begin{lstlisting}[language=Python,firstnumber=27] ... \end{lstlisting}
%-> \begin{lstlisting}[language=Python,numbers=none] ... \end{lstlisting}
%-> \lstinline[language=JAVA]{...}

View File

@ -0,0 +1,173 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Pattern;
public class Stegano1
{
public static void main(String[] args) {
// Strings to hold the arguments. mode is either A or E for "Add" or "Extract".
String mode, inputfile, outputfile, bitstring;
Boolean err = false; // Boolean to tell if the arguments were passed correctly or not
if (args.length > 1) { // checking that at least one argument was passed to main
// assigning the mode & inputfile arguments
mode = args[0];
inputfile = args[1];
if (inputfile.equals("")) { // checking that an inputfile was provided (String was not empty)
err = true;
}
else if ((mode.equals("A")) && (args.length > 3)){ // checking if the mode is "Add" & that the number of arguments provided was greater than 3
// assigning the outputfile & bitstring arguments
outputfile = args[2];
bitstring = args[3];
if (outputfile.equals("") || bitstring.equals("")) { // checking that neither the outputfile nor bitstring were empty strings
err = true;
}
else {
// hiding the bitstring
hide(inputfile, outputfile, bitstring);
}
}
else if (mode.equals("E")){ // checking if the mode is "Extract"
// retrieving (extracting) the bitstring from text
retrieve(inputfile);
}
else {
err = true;
}
}
else {
err = true;
}
if (err) {
System.out.println();
System.out.println("Use: Stegano1 <A:E><Input File><OutputFile><Bitstring>");
System.out.println("Example to add a bitvector to a file: Stegano1 A inp.txt out.txt 0010101");
System.out.println("Example to extract a bitvector from a file: Stegano1 E inp.txt");
}
}
// method to hide a bitstring in a copy the input file provided
static void hide(String inpFile, String outFile, String bitString) {
// to encode 2 bits with just one symbol, i'm going to represent the binary digits as an analog represenation of the number it represents plus one
// e.g., 00 will be represented as " " (1 space), 01 as " " (2 spaces), 10 as " " (3 spaces), and 11 as " " (4 spaces)
// the two bits are treated as a binary number, and then i add one to said binary number to get the number of spaces that will represent that number
BufferedReader reader; // declaring a BufferedReader for the input file
BufferedWriter writer; // declaring a BufferedWriter for the output file
try {
// initialising the reader & writer to FileReaders of their respective files (inpFile & outFile)
reader = new BufferedReader(new FileReader(inpFile));
writer = new BufferedWriter(new FileWriter(outFile));
String line = reader.readLine(); // reading in the first line from the input file
// checking if the number of bits in the bitstring is uneven, and if so, adding a '0' onto the end
if (bitString.length() % 2 != 0) { bitString = bitString.concat("0"); }
// will loop until there are no more lines to be read in from the input file (inpFile)
while (line != null) {
// if the bitString is not (yet) an empty String
if (!bitString.equals("")) {
// if the first 2-bit substring is 00, adding one space to the end of the line
if (bitString.substring(0,2).equals("00")) {
line = line.concat(" ");
}
// if the first 2-bit substring is 01, adding two spaces to the end of the line
else if (bitString.substring(0,2).equals("01")) {
line = line.concat(" ");
}
// if the first 2-bit substring is 10, adding three spaces to the end of the line
else if (bitString.substring(0,2).equals("10")) {
line = line.concat(" ");
}
// if the first 2-bit substring is 11, adding four spaces to the end of the line
else if (bitString.substring(0,2).equals("11")) {
line = line.concat(" ");
}
// removing the first two bits from the bitString now that they have been used
bitString = bitString.substring(2, bitString.length()); // replacing bitString with it's substring that goes from the third character to the last character
}
// writing the amended line to the output file
writer.write(line);
writer.newLine();
// reading the next line
line = reader.readLine();
}
// closing the reader & the writer
reader.close();
writer.close();
}
// catching any IOExceptions
catch (IOException e) {
e.printStackTrace();
}
}
// method to retrieve a hidden string from the input file provided
static void retrieve(String inpFile) {
BufferedReader reader; // declaring a BufferedReader for the input file (inpFile)
String message = "";
try {
reader = new BufferedReader(new FileReader(inpFile)); // initialising the reader to a FileReader of the input file (inpFile)
String line = reader.readLine(); // reading in the first line from the input file
// will loop until there are no more lines to be read in from the input file
while (line != null) {
// checking if the line ends in a space using a regular expression
if (Pattern.matches(".* $", line)) { // (checking if the String line contains any amount of any characters, followed by a space followed by the end of a line)
if (Pattern.matches(".* $", line)) { // checking if the line ends in four spaces using a regular expression
message = message.concat("11"); // concatenating "11" onto the end of the message String (four spaces represents "11")
}
else if (Pattern.matches(".* $", line)) { // checking if the line ends in three spaces using a regular expression
message = message.concat("10"); // concatenating "10" onto the end of the message String (three spaces represents "10")
}
else if (Pattern.matches(".* $", line)) { // (checking if the String line contains any amount of any characters, followed by two spaces followed by the end of a line)
message = message.concat("01"); // concatenating a "1" onto the message String (two spaces represent a "1")
}
else { // essentially, this "else" means "if the line ends with one space but not two"
message = message.concat("00"); // concatenating a "0" onto the message String (one space represents a "0")
}
}
else { // if the String does not end in a space, then there is no (more) message to read
break;
}
// reading the next line
line = reader.readLine();
}
// closing in the reader
reader.close();
// checking if the message String is empty so that an error message can be printed if no hidden message was found
if (message.equals("")) {
message = "Error: No hidden message found!";
}
// printing out the message
System.out.println(message);
}
// catching any IOExceptions
catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,49 @@
\addtolength{\hoffset}{-2.25cm}
\addtolength{\textwidth}{4.5cm}
\addtolength{\voffset}{-3.25cm}
\addtolength{\textheight}{5cm}
\setlength{\parskip}{0pt}
\setlength{\parindent}{0in}
%----------------------------------------------------------------------------------------
% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS
%----------------------------------------------------------------------------------------
\usepackage{blindtext} % Package to generate dummy text
\usepackage{charter} % Use the Charter font
\usepackage[utf8]{inputenc} % Use UTF-8 encoding
\usepackage{microtype} % Slightly tweak font spacing for aesthetics
\usepackage[english, ngerman]{babel} % Language hyphenation and typographical rules
\usepackage{amsthm, amsmath, amssymb} % Mathematical typesetting
\usepackage{float} % Improved interface for floating objects
\usepackage[final, colorlinks = true,
linkcolor = black,
citecolor = black]{hyperref} % For hyperlinks in the PDF
\usepackage{graphicx, multicol} % Enhanced support for graphics
\usepackage{xcolor} % Driver-independent color extensions
\usepackage{marvosym, wasysym} % More symbols
\usepackage{rotating} % Rotation tools
\usepackage{censor} % Facilities for controlling restricted text
\usepackage{listings, style/lstlisting} % Environment for non-formatted code, !uses style file!
\usepackage{pseudocode} % Environment for specifying algorithms in a natural way
\usepackage{style/avm} % Environment for f-structures, !uses style file!
\usepackage{booktabs} % Enhances quality of tables
\usepackage{tikz-qtree} % Easy tree drawing tool
\tikzset{every tree node/.style={align=center,anchor=north},
level distance=2cm} % Configuration for q-trees
\usepackage{style/btree} % Configuration for b-trees and b+-trees, !uses style file!
\usepackage[backend=biber,style=numeric,
sorting=nyt]{biblatex} % Complete reimplementation of bibliographic facilities
\addbibresource{ecl.bib}
\usepackage{csquotes} % Context sensitive quotation facilities
\usepackage[yyyymmdd]{datetime} % Uses YEAR-MONTH-DAY format for dates
\renewcommand{\dateseparator}{-} % Sets dateseparator to '-'
\usepackage{fancyhdr} % Headers and footers
\pagestyle{fancy} % All pages have headers and footers
\fancyhead{}\renewcommand{\headrulewidth}{0pt} % Blank out the default header
\fancyfoot[L]{} % Custom footer text
\fancyfoot[C]{} % Custom footer text
\fancyfoot[R]{\thepage} % Custom footer text
\newcommand{\note}[1]{\marginpar{\scriptsize \textcolor{red}{#1}}} % Enables comments in red on margin
%----------------------------------------------------------------------------------------

View File

@ -0,0 +1,383 @@
\documentclass[a4paper]{article}
\input{head}
\begin{document}
%-------------------------------
% TITLE SECTION
%-------------------------------
\fancyhead[C]{}
\hrule \medskip % Upper rule
\begin{minipage}{0.295\textwidth}
\raggedright
\footnotesize
Andrew Hayes \hfill\\
21321503 \hfill\\
a.hayes18@nuigalway.ie
\end{minipage}
\begin{minipage}{0.4\textwidth}
\centering
\large
CT255 Assignment 3\\
\normalsize
Steganography\\
\end{minipage}
\begin{minipage}{0.295\textwidth}
\raggedleft
\today\hfill\\
\end{minipage}
\medskip\hrule
\bigskip
%-------------------------------
% CONTENTS
%-------------------------------
\section{Problem 1}
\subsection{Code}
\begin{lstlisting}[language=Java]
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Pattern;
public class Stegano1
{
public static void main(String[] args) {
// Strings to hold the arguments. mode is either A or E for "Add" or "Extract".
String mode, inputfile, outputfile, bitstring;
Boolean err = false; // Boolean to tell if the arguments were passed correctly or not
if (args.length > 1) { // checking that at least one argument was passed to main
// assigning the mode & inputfile arguments
mode = args[0];
inputfile = args[1];
if (inputfile.equals("")) { // checking that an inputfile was provided (String was not empty)
err = true;
}
else if ((mode.equals("A")) && (args.length > 3)){ // checking if the mode is "Add" & that the number of arguments provided was greater than 3
// assigning the outputfile & bitstring arguments
outputfile = args[2];
bitstring = args[3];
if (outputfile.equals("") || bitstring.equals("")) { // checking that neither the outputfile nor bitstring were empty strings
err = true;
}
else {
// hiding the bitstring
hide(inputfile, outputfile, bitstring);
}
}
else if (mode.equals("E")){ // checking if the mode is "Extract"
// retrieving (extracting) the bitstring from text
retrieve(inputfile);
}
else {
err = true;
}
}
else {
err = true;
}
if (err) {
System.out.println();
System.out.println("Use: Stegano1 <A:E><Input File><OutputFile><Bitstring>");
System.out.println("Example to add a bitvector to a file: Stegano1 A inp.txt out.txt 0010101");
System.out.println("Example to extract a bitvector from a file: Stegano1 E inp.txt");
}
}
// method to hide a bitstring in a copy the input file provided
static void hide(String inpFile, String outFile, String bitString) {
BufferedReader reader; // declaring a BufferedReader for the input file
BufferedWriter writer; // declaring a BufferedWriter for the output file
try {
// initialising the reader & writer to FileReaders of their respective files (inpFile & outFile)
reader = new BufferedReader(new FileReader(inpFile));
writer = new BufferedWriter(new FileWriter(outFile));
String line = reader.readLine(); // reading in the first line from the input file
// will loop until there are no more lines to be read in from the input file (inpFile)
while (line != null) {
// if the bitString is not (yet) an empty String
if (!bitString.equals("")) {
// if the first bit (char) of the bitString is 0
if (bitString.charAt(0) == '0') { // note: must use '' instead of "" for char literals
line = line.concat(" "); // concatenating a space to the end of the line (one space represents a 0)
}
// if the first bit of the bitString is 1
if (bitString.charAt(0) == '1') {
line = line.concat(" "); // concatenating two spaces to the end of the line (two spaces represents a 1)
}
// removing the first bit from the bitString now that it has been used
bitString = bitString.substring(1, bitString.length()); // replacing bitString with it's substring that goes from the second character to the last character
}
// writing the amended line to the output file
writer.write(line);
writer.newLine();
// reading the next line
line = reader.readLine();
}
// closing the reader & the writer
reader.close();
writer.close();
}
// catching any IOExceptions
catch (IOException e) {
e.printStackTrace();
}
}
// method to retrieve a hidden string from the input file provided
static void retrieve(String inpFile) {
BufferedReader reader; // declaring a BufferedReader for the input file (inpFile)
String message = "";
try {
reader = new BufferedReader(new FileReader(inpFile)); // initialising the reader to a FileReader of the input file (inpFile)
String line = reader.readLine(); // reading in the first line from the input file
// will loop until there are no more lines to be read in from the input file
while (line != null) {
// checking if the line ends in a space using a regular expression
if (Pattern.matches(".* $", line)) { // (checking if the String line contains any amount of any characters, followed by a space followed by the end of a line)
// checking if the line ends in two spaces using a regular expression
if (Pattern.matches(".* $", line)) { // (checking if the String line contains any amount of any characters, followed by two spaces followed by the end of a line)
message = message.concat("1"); // concatenating a "1" onto the message String (two spaces represent a "1")
}
else { // essentially, this "else" means "if the line ends with one space but not two"
message = message.concat("0"); // concatenating a "0" onto the message String (one space represents a "0")
}
}
else { // if the String does not end in a space, then there is no (more) message to read
break;
}
// reading the next line
line = reader.readLine();
}
// closing in the reader
reader.close();
// checking if the message String is empty so that an error message can be printed if no hidden message was found
if (message.equals("")) {
message = "Error: No hidden message found!";
}
// printing out the message
System.out.println(message);
}
// catching any IOExceptions
catch (IOException e) {
e.printStackTrace();
}
}
}
\end{lstlisting}
\subsection{Screenshot of Compilation \& Output}
\includegraphics[width = 15cm]{output1.png}
\bigskip
%------------------------------------------------
\section{Problem 2}
\subsection{Code}
\begin{lstlisting}[language=java]
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Pattern;
public class Stegano1
{
public static void main(String[] args) {
// Strings to hold the arguments. mode is either A or E for "Add" or "Extract".
String mode, inputfile, outputfile, bitstring;
Boolean err = false; // Boolean to tell if the arguments were passed correctly or not
if (args.length > 1) { // checking that at least one argument was passed to main
// assigning the mode & inputfile arguments
mode = args[0];
inputfile = args[1];
if (inputfile.equals("")) { // checking that an inputfile was provided (String was not empty)
err = true;
}
else if ((mode.equals("A")) && (args.length > 3)){ // checking if the mode is "Add" & that the number of arguments provided was greater than 3
// assigning the outputfile & bitstring arguments
outputfile = args[2];
bitstring = args[3];
if (outputfile.equals("") || bitstring.equals("")) { // checking that neither the outputfile nor bitstring were empty strings
err = true;
}
else {
// hiding the bitstring
hide(inputfile, outputfile, bitstring);
}
}
else if (mode.equals("E")){ // checking if the mode is "Extract"
// retrieving (extracting) the bitstring from text
retrieve(inputfile);
}
else {
err = true;
}
}
else {
err = true;
}
if (err) {
System.out.println();
System.out.println("Use: Stegano1 <A:E><Input File><OutputFile><Bitstring>");
System.out.println("Example to add a bitvector to a file: Stegano1 A inp.txt out.txt 0010101");
System.out.println("Example to extract a bitvector from a file: Stegano1 E inp.txt");
}
}
// method to hide a bitstring in a copy the input file provided
static void hide(String inpFile, String outFile, String bitString) {
// to encode 2 bits with just one symbol, i'm going to represent the binary digits as an analog represenation of the number it represents plus one
// e.g., 00 will be represented as " " (1 space), 01 as " " (2 spaces), 10 as " " (3 spaces), and 11 as " " (4 spaces)
// the two bits are treated as a binary number, and then i add one to said binary number to get the number of spaces that will represent that number
BufferedReader reader; // declaring a BufferedReader for the input file
BufferedWriter writer; // declaring a BufferedWriter for the output file
try {
// initialising the reader & writer to FileReaders of their respective files (inpFile & outFile)
reader = new BufferedReader(new FileReader(inpFile));
writer = new BufferedWriter(new FileWriter(outFile));
String line = reader.readLine(); // reading in the first line from the input file
// checking if the number of bits in the bitstring is uneven, and if so, adding a '0' onto the end
if (bitString.length() % 2 != 0) { bitString = bitString.concat("0"); }
// will loop until there are no more lines to be read in from the input file (inpFile)
while (line != null) {
// if the bitString is not (yet) an empty String
if (!bitString.equals("")) {
// if the first 2-bit substring is 00, adding one space to the end of the line
if (bitString.substring(0,2).equals("00")) {
line = line.concat(" ");
}
// if the first 2-bit substring is 01, adding two spaces to the end of the line
else if (bitString.substring(0,2).equals("01")) {
line = line.concat(" ");
}
// if the first 2-bit substring is 10, adding three spaces to the end of the line
else if (bitString.substring(0,2).equals("10")) {
line = line.concat(" ");
}
// if the first 2-bit substring is 11, adding four spaces to the end of the line
else if (bitString.substring(0,2).equals("11")) {
line = line.concat(" ");
}
// removing the first two bits from the bitString now that they have been used
bitString = bitString.substring(2, bitString.length()); // replacing bitString with it's substring that goes from the third character to the last character
}
// writing the amended line to the output file
writer.write(line);
writer.newLine();
// reading the next line
line = reader.readLine();
}
// closing the reader & the writer
reader.close();
writer.close();
}
// catching any IOExceptions
catch (IOException e) {
e.printStackTrace();
}
}
// method to retrieve a hidden string from the input file provided
static void retrieve(String inpFile) {
BufferedReader reader; // declaring a BufferedReader for the input file (inpFile)
String message = "";
try {
reader = new BufferedReader(new FileReader(inpFile)); // initialising the reader to a FileReader of the input file (inpFile)
String line = reader.readLine(); // reading in the first line from the input file
// will loop until there are no more lines to be read in from the input file
while (line != null) {
// checking if the line ends in a space using a regular expression
if (Pattern.matches(".* $", line)) { // (checking if the String line contains any amount of any characters, followed by a space followed by the end of a line)
if (Pattern.matches(".* $", line)) { // checking if the line ends in four spaces using a regular expression
message = message.concat("11"); // concatenating "11" onto the end of the message String (four spaces represents "11")
}
else if (Pattern.matches(".* $", line)) { // checking if the line ends in three spaces using a regular expression
message = message.concat("10"); // concatenating "10" onto the end of the message String (three spaces represents "10")
}
else if (Pattern.matches(".* $", line)) { // (checking if the String line contains any amount of any characters, followed by two spaces followed by the end of a line)
message = message.concat("01"); // concatenating a "1" onto the message String (two spaces represent a "1")
}
else { // essentially, this "else" means "if the line ends with one space but not two"
message = message.concat("00"); // concatenating a "0" onto the message String (one space represents a "0")
}
}
else { // if the String does not end in a space, then there is no (more) message to read
break;
}
// reading the next line
line = reader.readLine();
}
// closing in the reader
reader.close();
// checking if the message String is empty so that an error message can be printed if no hidden message was found
if (message.equals("")) {
message = "Error: No hidden message found!";
}
// printing out the message
System.out.println(message);
}
// catching any IOExceptions
catch (IOException e) {
e.printStackTrace();
}
}
}
\end{lstlisting}
\subsection{Output}
\includegraphics[width = 15cm]{output2.png}
\end{document}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,165 @@
% avm.sty -- for attribute-value matrices -- mar 29, 1992; rev. dec 6, 1993
% (c) 1992 christopher manning (manning@csli.stanford.edu) -- see avm.doc.tex
\newif\ifavmactive\newif\ifavmsorted\newif\ifavmlabeled
\newif\ifavmcenter\newif\ifavmbottom
\newif\ifavmbottomright\newif\ifavmtopleft\newif\ifavmtopright
\newdimen\avmdimen
\newbox\avmboxone\newbox\avmboxthree
\def\avmoptions#1{\avmactivefalse\avmsortedfalse\avmlabeledfalse
\avmcenterfalse\avmbottomfalse
\avmbottomrightfalse\avmtopleftfalse\avmtoprightfalse
\def\more{#1}\ifx\more\empty\else\avmjoptions#1,\@nil\fi}
\def\avmjoptions#1,#2\@nil{\def\more{#2}\csname avm#1true\endcsname
\ifx\more\empty\else\avmjoptions#2\@nil\fi}
\def\avmfont#1{\def\avmjfont{#1}}
\def\avmjfont{}
\def\avmvalfont#1{\def\avmjvalfont{#1}}
\def\avmjvalfont{}
\def\avmsortfont#1{\def\avmjsortfont{#1}}
\def\avmjsortfont{}
\def\avmhskip#1{\def\avmjhskip{#1}}
\def\avmjhskip{1em}
\def\avmbskip#1{\def\avmjbskip{#1}}
\def\avmjbskip{0em}
\def\avmvskip#1{\def\avmjvskip{#1}}
\def\avmjvskip{0.385ex}%was .3875
\def\avmjprolog#1{$\mskip-\thinmuskip
\left#1\hskip\avmjbskip\vcenter\bgroup\vskip\avmjvskip
\ialign\bgroup\avmjfont
\strut ##\unskip\hfil
&&\hskip\avmjhskip\avmjvalfont ##\unskip\hfil\cr}
\def\avmjpostlog#1{\crcr\egroup\vskip\avmjvskip\egroup
\hskip\avmjbskip\right#1\mskip-\thinmuskip$\ignorespaces}
\def\avmjcatcode{\let\lparen=(\let\rparen=)\catcode`\[=13\catcode`\]=13
\catcode`\<=13\catcode`\@=13\catcode`\(=13\catcode`\)=13
\catcode`\>=13\catcode`\|=13}
{\avmjcatcode % new group: redefine above catcodes as active
\gdef\specialavm{\avmjcatcode
\def({\avmjprolog\lparen}%
\def){\avmjpostlog\rparen}%
\def<{\avmjprolog\langle}%
\def>{\avmjpostlog\rangle}%
\ifavmsorted
\def[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox2=\hbox
\bgroup\avmjprolog\lbrack}%
\def]{\avmjpostlog\rbrack\egroup\avmjsort}%
\else\ifavmlabeled
\def[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
\def]{\avmjpostlog]\egroup\node{\more}{\box2}}%
\else
\def[{\avmjprolog\lbrack}%
\def]{\avmjpostlog\rbrack}%
\fi\fi
%
\def\<{$\langle$}\def\>{$\rangle$}%
\def\({\lparen}\def\){\rparen}%
\def\[{\lbrack}\def\]{\rbrack}%
\def|{$\,\vert\,$}%
\def@##1{\avmbox{##1}}%
} % end defn of \specialavm
} % restore active catcodes
\long\def\avm{\begingroup
\ifavmactive\specialavm
\else
\def\({\avmjprolog(}%
\def\){\avmjpostlog)}%
\def\<{\avmjprolog\langle}%
\def\>{\avmjpostlog\rangle}%
%
\ifavmsorted
\def\[##1{\setbox\avmboxthree=\hbox{\avmjsortfont##1\/}\setbox
2=\hbox\bgroup\avmjprolog[}%
\def\]{\avmjpostlog]\egroup\avmjsort}%
\else\ifavmlabeled
\def\[##1{\def\more{##1}\setbox2=\hbox\bgroup\avmjprolog[}%
\def\]{\avmjpostlog]\egroup\node{\more}{\box2}}%
\else
\def\[{\avmjprolog[}%
\def\]{\avmjpostlog]}%
\fi\fi
%
\def\|{$\,\vert\,$}%
\def\@##1{\avmbox{##1}}%
\fi % end not active
%
\ifx\LaTeX\undefined\def\\{\cr}% running under TeX
\else \def\\{\@tabularcr}% Leverage off LaTeX's \\*[dimen] options
\fi
\def\!{\node}%
\long\def\avmjsort{\dimen2=\ht2\advance\dimen2 by -.25\baselineskip
\global\dimen\avmdimen=\wd\avmboxthree
\ifavmtopleft \raise\dimen2\llap{\box\avmboxthree}\box2%
\else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
\else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
\else \lower\dimen2\llap{\box\avmboxthree}\box2%
\fi\fi\fi}%
\long\def\sort##1##2{\setbox2=\hbox{##2}\setbox
\avmboxthree=\hbox{\avmjsortfont##1\/}\dimen2=\ht2
\advance\dimen2 by -.25\baselineskip
\ifavmtopleft \raise\dimen2\box\avmboxthree\box2%
\else\ifavmtopright \box2\raise\dimen2\box\avmboxthree%
\else\ifavmbottomright \box2\lower\dimen2\box\avmboxthree%
\else \lower\dimen2\box\avmboxthree\box2%
\fi\fi\fi}%
\long\def\osort##1##2{\setbox2=\hbox{##2}\setbox
\avmboxthree=\hbox{\avmjsortfont ##1\/}\avmjsort}%
\def\avml{\avmjprolog.}%
\def\avmr{\avmjpostlog.}%
\def\avmb##1{\node{##1}{\lbrack\;\rbrack}}%
\def\avmd##1{\node{##1}{---}}%
\def\q##1{\ifx ##1\{$\lbrace$\else
\ifx ##1\}$\rbrace$\else
\ifx ##1<$\langle$\else
\ifx ##1>$\rangle$\fi \fi \fi \fi}%
\def\{{\avmjprolog\lbrace}%
\def\}{\avmjpostlog\rbrace}%
\def\;{\hskip\avmjhskip}%
\def\avmspan##1{\multispan2\strut ##1\expandafter\hfil}%
\avmjfont
\openup\avmjvskip
\setbox\avmboxone=\hbox\bgroup\ignorespaces
} % end defn of \avm
\def\endavm{\egroup\ifvmode\leavevmode\fi % this if is useful!
\ifavmsorted\null\hskip\dimen\avmdimen\fi
\ifavmcenter
\box\avmboxone
\else \ifavmbottom
\lower.575\baselineskip\hbox{\vbox{\box\avmboxone\null}}%
\else
% the next bit is ripped off from Emma's \evnup in lingmacros.sty
\dimen2=\ht\avmboxone\advance\dimen2 by -.725\baselineskip
\lower\dimen2\box\avmboxone
\fi \fi \endgroup}
% based on TeXbook exercise 21.3
\def\avmbox#1{\setbox2=\hbox{$\scriptstyle #1$}\lower.2ex\vbox{\hrule
\hbox{\vrule\kern1.25pt
\vbox{\kern1.25pt\box2\kern1.25pt}\kern1.25pt\vrule}\hrule}}
% ============ COSTOM CONFIGURATION =============
\avmfont{\sc}
\avmoptions{sorted,active}
\avmvalfont{\rm}
\avmsortfont{\scriptsize\it}
% ===============================================

View File

@ -0,0 +1,131 @@
%% Last Modified: Thu Oct 18 18:26:25 2007.
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{style/btree}
\typeout{Document Style `weiw_BTree - Support drawing B+-Tree (ver 0.999)}
\RequirePackage{tikz}
\RequirePackage{ifthen}
% use libraries
\usetikzlibrary{arrows,shapes,decorations,matrix}
%% global declaration
\tikzstyle{btreeptr} = [draw, semithick, minimum height=2em]
\tikzstyle{btreeval} = [draw, semithick, minimum size=2em]
\tikzstyle{btreevale} = [draw,semithick, minimum size=2em]
\tikzstyle{btlink} = [draw, semithick, ->, >=triangle 45]
%% macro
%% helper macros
\newcommand{\suppressemptystr}[1]{% leave blank for entries in leaf nodes
\ifthenelse{\equal{#1}{}}%
{%
\relax%
}%
% Else
{%
#1\textsuperscript{*}%
}%
}%
\newcommand{\xyshift}[3]{% help to place the nodes
\begin{scope}[xshift=#1, yshift=#2]
#3
\end{scope}%
}
%% Common btree macros
\newcommand{\btreelink}[2]{% #1: src node; #2: dest node;
\draw[btlink] ([yshift=3pt] #1.south) -- (#2-b.north);
}
\newcommand{\btreelinknorth}[2]{% #1: src node; #2: dest node;
\draw[btlink] ([yshift=3pt] #1.south) -- (#2.north);
}
\newcommand{\btreetriangle}[2]{% #1: node name; #2 text inside
\node[anchor=north, regular polygon, regular polygon sides=3, draw] (#1) {#2};
}
%%======================================================================
%% btree with capacity = 4
\newcommand{\btreeinodefour}[5]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \& \node[btreeval] (#1-c) {#4}; \&
\node[btreeptr] (#1-4) {\vphantom{1}}; \& \node[btreeval] (#1-d) {#5}; \&
\node[btreeptr] (#1-5) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodefour}[5]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \&
\node[btreevale] (#1-c) {\suppressemptystr{#4}}; \&
\node[btreevale] (#1-d) {\suppressemptystr{#5}}; \\
};
}
%%======================================================================
%% btree with capacity = 3
\newcommand{\btreeinodethree}[4]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \& \node[btreeval] (#1-c) {#4}; \&
\node[btreeptr] (#1-4) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodethree}[4]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \&
\node[btreevale] (#1-c) {\suppressemptystr{#4}}; \\
};
}
%%======================================================================
%% btree with capacity = 2
\newcommand{\btreeinodetwo}[4]{%
\matrix [ampersand replacement=\&] (#1)
{
\node[btreeptr] (#1-1) {\vphantom{1}}; \& \node[btreeval] (#1-a) {#2}; \&
\node[btreeptr] (#1-2) {\vphantom{1}}; \& \node[btreeval] (#1-b) {#3}; \&
\node[btreeptr] (#1-3) {\vphantom{1}}; \\
};
}
\newcommand{\btreelnodetwo}[3]{%
\matrix [ampersand replacement=\&, outer sep=0pt, matrix anchor=north] (#1)
{
\node[btreevale] (#1-a) {\suppressemptystr{#2}}; \&
\node[btreevale] (#1-b) {\suppressemptystr{#3}}; \\
};
}
%%======================================================================
%% simple example
% \begin{center}
% \scalebox{0.7}{
% \begin{tikzpicture}
% %
% \btreeinodefour{root}{13}{17}{24}{30};
% \xyshift{-40mm}{-20mm}{\btreelnodefour{n1}{2}{3}{5}{7}}
% \xyshift{-0mm}{-20mm}{\btreelnodefour{n2}{14}{16}{}{}}
% \xyshift{40mm}{-20mm}{\btreelnodefour{n3}{19}{20}{22}{}}
% \xyshift{80mm}{-20mm}{\btreelnodefour{n4}{24}{27}{29}{}}
% \xyshift{120mm}{-20mm}{\btreelnodefour{n5}{33}{34}{38}{39}}
% %
% \foreach \x in {1,2,...,5} { \btreelink{root-\x}{n\x} }
% \end{tikzpicture}
% }
% \end{center}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,38 @@
% Source: ss17_wissschreib (Eva)
\lstset{
basicstyle=\ttfamily\scriptsize\mdseries,
keywordstyle=\bfseries\color[rgb]{0.171875, 0.242188, 0.3125},
identifierstyle=,
commentstyle=\color[rgb]{0.257813, 0.15625, 0},
stringstyle=\itshape\color[rgb]{0.0195313, 0.195313, 0.0117188},
numbers=left,
numberstyle=\tiny,
stepnumber=1,
breaklines=true,
frame=none,
showstringspaces=false,
tabsize=4,
backgroundcolor=\color[rgb]{0.98,0.98,0.98},
captionpos=b,
float=htbp,
language=Python,
xleftmargin=15pt,
xrightmargin=15pt
}
%(deutsche) Sonderzeichen
\lstset{literate=%
{Ä}{{\"A}}1
{Ö}{{\"O}}1
{Ü}{{\"U}}1
{ä}{{\"a}}1
{ö}{{\"o}}1
{ü}{{\"u}}1
{ß}{{\ss}}1
}
%Verwendung im Text:
%-> \begin{lstlisting}[language=Python,firstnumber=27] ... \end{lstlisting}
%-> \begin{lstlisting}[language=Python,numbers=none] ... \end{lstlisting}
%-> \lstinline[language=JAVA]{...}

View File

@ -0,0 +1,116 @@
/**
* CT255 - Assignment 3
* Skeleton code for Steganography assignment.
*
* @author Michael Schukat
* @version 1.0
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Stegano1
{
/**
* Constructor for objects of class Stegano1
*/
public Stegano1()
{
}
public static void main(String[] args) {
String arg1, arg2, arg3, arg4;
Boolean err = false;
if (args != null && args.length > 1) { // Check for minimum number of arguments
arg1 = args[0];
arg2 = args[1];
if (arg2 == "") {
err = true;
}
else if ((arg1 == "A") && (args.length > 3)){
// Get other arguments
arg3 = args[2];
arg4 = args[3];
if (arg3 == "" || arg4 == "") {
err = true;
}
else {
// Hide bitstring
hide(arg2, arg3, arg4);
}
}
else if (arg1 == "E"){
// Extract bitstring from text
retrieve(arg2);
}
else {
err = true;
}
}
else {
err = true;
}
if (err == true) {
System.out.println();
System.out.println("Use: Stegano1 <A:E><Input File><OutputFile><Bitstring>");
System.out.println("Example: Stegano1 A inp.txt out.txt 0010101");
System.out.println("Example: Stegano1 E inp.txt");
}
}
static void hide(String inpFile, String outFile, String binString) {
//
BufferedReader reader;
BufferedWriter writer;
try {
reader = new BufferedReader(new FileReader(inpFile));
writer = new BufferedWriter(new FileWriter(outFile));
String line = reader.readLine();
while (line != null) {
// Your code starts here
// Store amended line in output file
writer.write(line);
writer.newLine();
// read next line
line = reader.readLine();
}
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
static void retrieve(String inpFile) {
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(inpFile));
String line = reader.readLine();
while (line != null) {
// Your code starts here
// System.out.println(line);
// read next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,57 @@
The Stolen Child
Where dips the rocky highland
Of Sleuth Wood in the lake,
There lies a leafy island
Where flapping herons wake
The drowsy water rats;
There we've hid our faery vats,
Full of berrys
And of reddest stolen cherries.
Come away, O human child!
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than you can understand.
Where the wave of moonlight glosses
The dim gray sands with light,
Far off by furthest Rosses
We foot it all the night,
Weaving olden dances
Mingling hands and mingling glances
Till the moon has taken flight;
To and fro we leap
And chase the frothy bubbles,
While the world is full of troubles
And anxious in its sleep.
Come away, O human child!
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than you can understand.
Where the wandering water gushes
From the hills above Glen-Car,
In pools among the rushes
That scarce could bathe a star,
We seek for slumbering trout
And whispering in their ears
Give them unquiet dreams;
Leaning softly out
From ferns that drop their tears
Over the young streams.
Come away, O human child!
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than you can understand.
Away with us he's going,
The solemn-eyed:
He'll hear no more the lowing
Of the calves on the warm hillside
Or the kettle on the hob
Sing peace into his breast,
Or see the brown mice bob
Round and round the oatmeal chest.
For he comes, the human child,
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than he can understand.

View File

@ -0,0 +1,57 @@
The Stolen Child
Where dips the rocky highland
Of Sleuth Wood in the lake,
There lies a leafy island
Where flapping herons wake
The drowsy water rats;
There we've hid our faery vats,
Full of berrys
And of reddest stolen cherries.
Come away, O human child!
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than you can understand.
Where the wave of moonlight glosses
The dim gray sands with light,
Far off by furthest Rosses
We foot it all the night,
Weaving olden dances
Mingling hands and mingling glances
Till the moon has taken flight;
To and fro we leap
And chase the frothy bubbles,
While the world is full of troubles
And anxious in its sleep.
Come away, O human child!
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than you can understand.
Where the wandering water gushes
From the hills above Glen-Car,
In pools among the rushes
That scarce could bathe a star,
We seek for slumbering trout
And whispering in their ears
Give them unquiet dreams;
Leaning softly out
From ferns that drop their tears
Over the young streams.
Come away, O human child!
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than you can understand.
Away with us he's going,
The solemn-eyed:
He'll hear no more the lowing
Of the calves on the warm hillside
Or the kettle on the hob
Sing peace into his breast,
Or see the brown mice bob
Round and round the oatmeal chest.
For he comes, the human child,
To the waters and the wild
With a faery, hand in hand,
For the world's more full of weeping than he can understand.

View File

@ -0,0 +1,91 @@
import java.util.ArrayList;
public class DiffieHellman {
public static void main(String[] args) {
generate_params();
}
// method to generate the random DH parameters
public static void generate_params() {
int prime = generate_prime(); // generating a prime number
System.out.println("prime: " + prime);
int primitive_root = generate_primitive_root(prime); // generating a primitive root of that prime
System.out.println("prime: " + prime + ". primtive root : " + primitive_root);
}
// method to generate a prime number in the range 10000 - 100000
public static int generate_prime() {
// generating an ArrayList of prime numbers in the range 10,000 to 100,000 using the Sieve of Eratosthenes
// creating a list of consecutive integers from 2 through 100,000
ArrayList<Integer> integers = new ArrayList<Integer>();
for (int n = 2; n <= 100000; n++) {
integers.add(n);
}
// initially, let p equal 2, the smallest prime number in the list.
int p = integers.get(0);
// variable to hold the number of known primes in the ArrayList
int primes_count = 1;
// looping while p is less than the final value in the list
while (p < integers.get(integers.size() - 1)) {
// removing the mutliples of p from the list
for (int i = 2; (i * p) <= integers.get(integers.size() - 1); i++) {
integers.remove(Integer.valueOf(i * p));
}
// let p equal the new smallest element in the ArrayList
p = integers.get(primes_count++);
}
// cutting out the section of the ArrayList that contains prime number outside the appropriate range
while (integers.get(0) < 10000) { // removing the first element of the ArrayList while the first index of the ArrayList holds a value less than 10,000
integers.remove(0);
}
// selecting the element at a random index in the ArrayList of primes as our prime number
int prime = integers.get((int) (Math.random() * (integers.size() - 1)));
return prime;
}
public static int generate_primitive_root(int prime) {
// ArrayList<Integer> primitive_roots = new ArrayList<Integer>(); // ArrayList to hold the primitive roots found
// looping through all the numbers in the range 2 to the prime minus 1 to see if they're primitive roots of the prime, breaking when we find the first primitive root
for (int n = 3; n < prime - 1; n++) {
boolean is_n_a_primtive_root = true; // boolean to tell whether or not n is a primtive root
ArrayList<Integer> distinct_values = new ArrayList<Integer>(); // ArrayList to hold the distinct values of a candidate primitive root modulo the prime
// loop to check if n is a primitive root by raising it to the power of x modulo the prime
for (int x = 2; x < prime - 2; x++) {
// setting is_n_a_primtive_root to false and breaking out of the loop if n to the power of x modulo the prime is already in the distinct_values ArrayList
if (distinct_values.contains((n^x) % prime)) {
is_n_a_primtive_root = false;
System.out.println(n + " is not a primitive root");
break;
}
else {
distinct_values.add((n^x) % prime);
}
}
// adding n to the list of primitive roots if it is a primitive root of the prime passed to the function
if (is_n_a_primtive_root) {
// primitive_roots.add(n);
return n;
}
}
// selecting a random value in the list of primitive roots to be our primtitive root
// int random_primitive_root = primitive_roots.get((int) (Math.random() * (primitive_roots.size() - 1)));
// int random_primitive_root = -1;
// return random_primitive_root;
//
// returning -1 if no primitive root found
return -1;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,78 @@
---
title: "Assignment 2"
author: "Andrew Hayes, id = 21321503"
date: "`r format(Sys.time(), '%d %B, %Y')`"
output:
word_document: default
pdf_document: default
---
## Starting with R-Markdown
In the following R-Markdown document some data are created followed by calculation of some summary statistics and display of graphical summaries. All the results are embedded for you in the report when you `knit` the document into a report.
The following `R` chunk creates a dataset in a vector and stores it in `R`'s memory using the name `x`. You will have been given some directions in how to adapt this dataset on Blackboard.
```{r}
x = c(10, 23, 14, 12, 34, 26, 28, 24)
```
The mean of this data is
```{r}
mean(x)
```
The summary statistics (minimum, maximum, $Q_1$, median, mean and $Q_3$) obtained from the `summary()` function are:
```{r}
# Insert your code here
summary(x)
```
The five number summary which uses Tukey's method to estimate the lower and upper quartiles ($Q_1$ and $Q_3$) is given below. Notice the small differences in these quartiles.
```{r}
# Insert your code here
fivenum(x)
```
The boxplot of the data below also uses Tukey's method. I would describe the shape of the distribution using the boxplot as right-skewed, as the tail on the right is significantly longer than the tail on the left. However, the median is offset to the right of the box, which would normally indicate a left-skew. One possible reason for this inconsistency is the small size of the dataset used for this boxplot, as boxplots are not very accurate for small data sets.
```{r}
boxplot(x)
```
A histogram is given below. I would describe the shape of the distribution using the histogram as right-skewed, as it peaks on the left, and decreases as it goes to the right.
```{r}
hist(x)
```
Use the help system in `R` to learn how to use the `breaks` argument in the `hist` function to include around 10 breakpoints. To use the help system type `help(hist)`
```{r}
hist(x, breaks = 10)
```

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,429 @@
---
title: "Reading Datafiles into R"
output:
word_document: default
html_document: default
pdf_document: default
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)
```
So far we have learned how to summarise (both numerically and graphically) different types of variables. We also learned how to produce numerical and graphical summaries of a variable across different groups of another categorical variable. But all the variables we used so far are from datasets that are already available in $\texttt{R}$.
A key next skill to learn is to import datasets into $\texttt{R}$. There are a lot of common mistakes when downloading files using browsers and then reading them into R. So we have produced a set of slides explaining these and how to avoid or overcome them, entitled "Working with R or R-Markdown and Datafiles". You may wish to read these slides first. They are posted with this lab material and in the Discussion Board.
## Reading datasets into `R`
The datasets we want to import into $\texttt{R}$ might be in different file format, e.g. ".csv", ".xlsx", ".sav", ".dat", ".xml", etc. Among all these file format ".csv" is the simplest and most portable (from one machine to the other) file format. When working with different people you cannot assume they a particular piece of software (e.g. Excel), and you need to be aware that many datafile formats do not have well defined standards so can be unreliable when sharing across different systems.
It is possible to import dataset in any of the file formats listed above and many others besides. But for the purpose of demonstration, we will show you how to import a dataset in ".csv" format using the function `read.csv()`.
**Firstly, you need to ensure the ".csv" file and this markdown file are stored in the same folder. Next ensure `R` is using that folder as the working directory (go to Session > Set Working Directory > To Source File Location if you need to set it).**
# Gapminder Dataset
We are going to use the gapminder dataset which is available in the "gapminder.csv" file. The dataset contains life expectancy at birth (under `lifeExp` variable name), total population (`pop`), and GDP per capita (`gdpPercap`) of 142 different countries from five different continents over 1952 to 2007. You can find more information and more variables from [here](https://www.gapminder.org/data/). Hans Rosling, the co-founder and chairman of the Gapminder Foundation, gave a mesmerizing Ted talk on this data which you can watch [here](https://www.ted.com/talks/hans_rosling_the_best_stats_you_ve_ever_seen?language=en).
The following code chunk reads the "gapminder.csv" into an $\texttt{R}$ object `gapminder`. If you get an error message, please read the slides on "Working with R or R-Markdown and Datafiles" and if you cannot resolve the problem discuss it with the tutor.
```{r }
library(tidyverse)
gapminder = read.csv("gapminder.csv")
```
The first thing to do when reading a dataset into statistical software is to check it has been read in correctly. You can get an overview of the dataset using the `glimpse()` function.
```{r }
gapminder %>% glimpse()
```
To understand the dataset contents, please complete the following task
**Task 1:**
* What is the experimental unit here?
* What is the dimension of the dataset (number of rows and columns)?
```{r}
```
## Filtering rows with the `filter()` function
You can see that there are 1,704 (=142*12) rows in the dataset along with 6 columns. The unit of observation here is country, since all the information available here belong to countries. In the `mtcars` dataset the experiments units were a particular model of car and for the `titanic_train` dataset it was a passenger. However, the `gapminder` dataset is somewhat more complex in the sense that for the `mtcars` dataset each car occupied only one row and for the `titanic_train` dataset each passenger occupied only one row of the dataset but for the `gapminder` dataset each country occupies 12 rows of the dataset. For a particular country, these 12 rows contain information related to different year of data collection.
Now, if we want to calculate the average population of European countries in 2007, we simply cannot use `summaries(mean(pop))` because it will give the average population of all the countries across all the years. So we have to keep the rows corresponding to European countries for 2007 by filtering out the rows we do not want. The `filter()` function from the `tidyverse` package can help us to keep the rows corresponding to European countries for 2007.
Run the code below. `"Europe"` is a value for the `continent` variable and `2007` is a value for the `year` variable. To keep the rows corresponding to the `"Europe"` value of the `continent` variable we can use `filter(continent == "Europe")`. To keep the rows corresponding to the `2007` value of the `year` variable we can use `filter(year == 2007)`. But to keep the rows belonging to both of them we need to use `filter(continent == "Europe" & year == 2007)`. Here we used a logical operator `&`. If you are not sure how it works please revisit the first lab.
```{r , max.print=5}
library(tidyverse)
gapminder %>% filter(continent == "Europe" & year == 2007)
```
Instead of using the logical operator `&` we can separate each condition in the `filter()` function with a comma. Take a look at the help for the `filter()` function typing `help(filter)` in the `R` Console, scroll down to "Arguments" and the entry for `...` which explains that it just combines them with an `&` operator.
```{r , max.print=5}
gapminder %>% filter(continent == "Europe", year == 2007)
```
**Task 2:** In the following code chunk, use the `filter()` function to keep the rows corresponding to the countries in the Americas only for the year 1952.
```{r}
```
## Selecting Columns With the `select()` Function
To keep the desired rows of a dataset we can use `filter()` function. Similarly, to keep the desired columns (variables) we can use the `select()` function. Here we select the country and population columns.
```{r}
gapminder %>%
filter(continent == "Europe" & year == 2007) %>%
select(country, pop)
```
**Task 3:** In the following code chunk, use the `select()` function to retain the `country`, `continent`, `year`, and `lifeExp` of the `gapminder` dataset.
```{r}
```
## Create a New Variable With the `mutate()` Function
The `filter()` and `select()` functions help us take "actions" on the dataset, so they are described as "verbs for data manipulation". The most commonly used verbs (functions) are: `select()` , `filter()`, `summarise()`, `mutate()`, and `arrange()`. Let's now demonstrate using the last two verbs.
The `pop` variable gives the population size for each countries. But it is hard to read such big numbers in the table above. So we could create a variable to store that number in millions (as population are usually expressed in millions). The `mutate()` function enables us to change variables in the dataset, including creating new variables.
In the code below we created a new variable `pop_mill` using the `mutate()` function by dividing the existing variable `pop` by a million (1,000,000). To keep only two decimal places we use the `round()` function.
```{r}
gapminder %>%
filter(continent == "Europe" & year == 2007) %>%
select(country, pop) %>%
mutate(pop_mill = round(pop / 1000000, 2))
```
**Task 4:** Create a new variable to store the total GDP of each country each year in billions (1,000,000,000) rounded to two decimal places. Hint: you need to multiply the GDP per capita by the total population to get total GDP of that year using the `mutate()` function.
```{r}
```
## Arrange rows of a dataset using `arrange()` function
We may also want to rank the five European countries by population size in 2007. We can do that using the `arrange()` function.
The code below arranges the dataset in **ascending** order by the `pop` variable, using the `arrange()` function. Not surprisingly Ireland made the list due its small size within Europe!
```{r}
gapminder %>%
filter(continent == "Europe" & year == 2007) %>%
select(country, pop) %>%
mutate(pop_mill = round(pop / 1000000, 2)) %>%
arrange(pop)
```
Now, if we want to see the top five most populous countries in Europe in 2007, we can use the `desc()` function inside the `arrange()` function. By default the `arrange()` function arrange the dataset from the smallest to the largest, but with the help of `desc()` function we can arrange the dataset from the largest to the smallest. See the code below, how we can use the `desc()` function inside the `arrange()` function to arrange the dataset from the largest to the smallest.
```{r}
gapminder %>%
filter(continent == "Europe" & year == 2007) %>%
select(country, pop) %>%
mutate(pop_mill = round(pop / 1000000, 2)) %>%
arrange(desc(pop))
```
**Task 5:** Now write the code below to find out the top five most economically productive countries (measured by GDP per capita) in Africa in 2002.
```{r}
```
## Filtering Rows Based on Multiple Values of a Variable
One way to filter more than one year at a time, or multiple countries, is to use the `%in%` operator.
Suppose we want to extract rows for Ireland and New Zealand, in both 2002 and 2007. In $\texttt{R}$, we can create a vector of these countries using `c("Ireland","New Zealand")` and the two years `c(2002, 2007)`.
The following code extracts the rows for these two countries for those two years. Note: the code deliberately uses single quotes to demonstrate that a **character string** can use double "" or single '' quotation marks.
```{r}
library(tidyverse)
gapminder %>%
filter(country %in% c('Ireland', 'New Zealand') & year %in% c(2002, 2007))
```
**Task 6:** Now write the code to extract rows corresponding to the Europe and Oceania from 1997 and 2007.
```{r}
```
## Revisiting `group_by()` function
Now, if we want to calculate the average GDP per capita for each of the continent by year, we could do that using the `group_by()` function that you are already familiar with.
The following code groups the dataset by `continent` and `year`, and then calculates the average GDP per capita for each continent per year
```{r message = FALSE, warning = FALSE}
gapminder %>%
group_by(continent, year) %>%
summarise(mean(gdpPercap))
```
You can see the resulting dataset has 60 rows because there are 12 year * 5 continent groups. The `summarise(mean(gdpPercap))` calculate the average GDP per capita over all the countries in that continent for that particular year.
If you want to count how many countries belong to a particular group and used this to calculate the average you can generate that number using the counting function `n()` inside the `summarise()` function. In statistics, "n" oft refers to as sample size.
From the code below, you can see for each year 52 countries used to calculate the average in Africa. If you scroll through the table then you can see it varies for each continent.
```{r}
gapminder %>%
group_by(continent, year) %>%
summarise(n(), mean(gdpPercap))
```
**Task 7:** Write code below to find out how many countries were used to calculate the mean for the Oceania continent over different years.
```{r}
```
## Creating a Cross-tabulation of Summary Statistics
To see how many countries are there in the dataset for each continent by years. We can generate a cross-table using the `table()` function as follows.
```{r}
gapminder %>%
select(continent, year) %>%
table()
```
Here, each row refers to the name of the continent, each column refers to the corresponding year, and the value in each cell of the table is the count of the entries. We may want to generate such a table but with the average value of the GDP per capita not the number of countries. How can we do that? To this we need to learn another function `pivot_wider()`.
Run the following code.
```{r}
gapminder %>%
group_by(continent, year) %>%
summarise(mean(gdpPercap)) %>%
pivot_wider(names_from = year, values_from = `mean(gdpPercap)`)
```
Now instead of the count, now we have average GDP per capita for each continent by year. It is very easy to compare the average GDP per capitat across year and continent.
It is slightly easier to code if you name the result from the `summary()` function as you can then just refer to it by name in `pivot_wider()`. Notice that the results are the same, but the code is maybe a little easier to understand.
```{r}
gapminder %>%
group_by(continent, year) %>%
summarise(meanGDP = mean(gdpPercap)) %>%
pivot_wider(names_from = year, values_from = meanGDP)
```
The `pivot_wider()` function *reshaped* the dataset by taking the column `year` and making each of its category as separate column. Then it fills the cell by taking values from the `meanGDP` variable. The part of the name of the function is "wider" because it makes the dataset "wide" by creating more variables than it has before. This type of transformation of dataset is called "reshaping". If this concept seems a bit advanced, do not worry we will discuss more about reshaping in future labs.
**Task 8:** Create a cross-table of continent and year with median life expectancy as the value for each cell.
```{r}
```
## Creating a Scatterplot With `geom_point()`
We have created a nice summary table to compare the average GDP per capita among different continents across different years. A graphical summary may be useful for audiences that don't like tables of numbers. **A picture is worth a thousand words, or numbers!*
Suppose, we want to see the change of life expectancy over the years for Ireland. First, we can filter the dataset to get the rows related to Ireland and then we can put `year` variable on the x-axis and `lifeExp` on the y-axis for the `ggplot`. Then we can represent each value as a point (geometric shape). In the following code we used the `geom_point()` function to create such a plot with "points" as geometric shape. This kind of plot is commonly known as *scatterplot*.
```{r}
gapminder %>%
filter(country == "Ireland") %>%
ggplot(aes(x = year, y = lifeExp)) +
geom_point() +
labs(x = "Year", y = "Life Expectancy at Birth")
```
**Task 9:** Create a scatterplot of Irish population against year to see how Irish population is changing.
```{r}
```
## Layered Graphics with `ggplot`
If we want to connect each of the dots by a line then we could use the `geom_line()` function in the plot above. In the code below, notice that we just added a new geometric shape in the plot and we have two plots (a scatter plot and a line plot) on the same plot! So we added a new *layer* by `geom_line()` function on the existing plot.
We can add as many layers we want to the plot to make it more informative. This is a very powerful feature of `ggplot`. It is part of the "grammar of graphics", hence the **gg* in `ggplot`.
```{r}
gapminder %>%
filter(country == "Ireland") %>%
ggplot(aes(x = year, y = lifeExp)) +
geom_point() +
geom_line() +
labs(x = "Year", y = "Life Expectancy at Birth")
```
**Task 10:** Create a layered graphics (with both a scatterplot and line plot) of Irish population against year.
```{r}
```
## Using `group` and `colour` aesthetics
Now, why only Ireland? You might want to add more countries to the plot to compare between countries. There is a very nice way we could do that in `ggplot` using the `group` aesthetic.
In the following code, we keep three countries and tell `ggplot` to create different lines for the different countries by specifying `group = country` inside the aesthetic `aes()` function which creates the environment for the plot.
```{r}
gapminder %>%
filter(country %in% c("Ireland", "Iceland", "Japan" )) %>%
ggplot(aes(x = year, y = lifeExp, group = country)) +
geom_point() +
geom_line() +
labs(x = "Year", y = "Life Expectancy at Birth")
```
The problem with the above plot is that we do not know what line represent what countries. To solve this, we can use `colour` aesthetic of `ggplot`.
```{r}
gapminder %>%
filter(country %in% c("Ireland", "Iceland", "Japan" )) %>%
ggplot(aes(x = year, y = lifeExp, group = country, colour = country)) +
geom_point() +
geom_line() +
labs(x = "Year", y = "Life Expectancy at Birth")
```
Now we have nice label for each country. This is called *legend* in plotting terminology.
**Task 11:** In the following R chunk, change the previous code to add two more countries: Norway and Italy. This time instead of life expectancy, plot total population in millions. Note: you have to create a new variable to convert the population in millions and you also need to change the level appropriately.
```{r}
```
## Plotting summary statistics
Now, if we wish to compare `lifeExp` across different continent, the line plot above might not be helpful because there are many countries belong to the same continent. So we first need to summarise them using a summary statistics (`median()` for example) and then can plot that for each continent over the years.
```{r}
gapminder %>%
group_by(continent, year) %>%
summarise(medianlifeExp = median(lifeExp)) %>%
ggplot(aes(x = year, y = medianlifeExp, colour = continent)) +
geom_point() +
geom_line() +
labs(x = "Year", y = "Median Life Expectancy at Birth")
```
**Task 12:** In the following code chunk, create a plot to compare mean GDP per capita across different continents over the years. Label the plot appropriately.
```{r}
```
## Object manipulation in `R`
Whenever you use `<-` of `=` operator in $\texttt{R}$ you are creating an object on the right and "assigning" it the name on the left of the operator. All the objects you create in an $\texttt{R}$ session are available in `R`'s memory for your to use. You can use the `objects()` or `ls()` functions to see what objects are available in the memory.
```{r}
objects()
ls()
```
The only object you should have stored in memory from this lab is the `gapminder` dataset, we imported at the beginning. No other objects have been created so far. Now, let's create some more objects.
```{r}
x = c(1, 2, 3, 4, 5)
y = c("A", "B", "C")
ireland = gapminder %>% filter(country == "Ireland")
```
and check what objects are available now.
```{r}
ls()
```
If you want to delete an object you can use the `rm()` function to do so. Lets delete the `x` object.
```{r}
rm("x")
ls()
```
You can also delete all the objects in the `R` memory using the following code.
```{r}
rm(list = ls())
```
After this complete deletion there will be nothing left, hence why the `ls()` function returns `character(0)` which mean a character vector with 0 entries, i.e. an empty list!
```{r}
ls()
```

View File

@ -0,0 +1,175 @@
---
title: "Investigating the Factors Affecting Birthweight"
author: "Andrew Hayes, id = 21321503"
date: "`r format(Sys.time(), '%d %B, %Y')`"
output:
pdf_document: default
word_document: default
---
# Question of Interest
Are the factors of smoking, previous history of hypertension or urinary irritability associated with whether babies were born with low birthweight (less than 2,500 grams)?
## Load the Libraries and Data Needed
Load the required libraries so you can use them, and then make the birthweight data available ('lowbwt') as follows:
```{r, message = FALSE, warning = FALSE}
library(tidyverse)
library(aplore3)
data(lowbwt)
```
The low birthweight data is from the "Applied Logistic Regression" textbook by Hosmer and Lemeshow. The following is a description of the variables in this dataset.
|Name| Description|
|:------|:------------------------------------------------------------------------|
|subject| identification code|
|low |low birthweight ("< 2500 g" or ">= 2500 g")|
|age |age of mother|
|lwt|weight at last menstrual period (pounds)|
|race |race (Black, White, Other)|
|smoke |smoked during pregnancy (Yes, No)|
|ptl |premature labour history (None, One, Two, etc.)|
|ht |history of hypertension (Yes, No)|
|ui |uterine irritability (Yes, No)|
|ftv |number of visits to physician during 1st trimester (None, One, Two, etc.)|
|bwt |birthweight (in grams)|
## Subjective Impressions
The key variable of interest is `low` which represents whether a baby is born with low birthweight, defined as a birthweight below 2,500 grams.
```{r}
lowbwt %>% select(low) %>% table()
```
Let's explore the association between history of hypertension and low birthweight by tabulating the data.
```{r}
lowbwt %>% select(low, ht) %>% table()
```
It seems there were not many mothers with hypertension, but the proportions of low weight babies is very much higher for mothers suffering from hypertension status than those that were not.
```{r}
lowbwt %>% select(low, ht) %>% table() %>% prop.table(margin = 2)
```
Task: In the following `R` chunk explore the association between uterine irritability and whether the babies were born with low birthweight, using both the counts and appropriate percentages. Explain the results in words.
```{r}
lowbwt %>% select(low, ui) %>% table()
lowbwt %>% select(low, ui) %>% table() %>% prop.table(margin = 2)
```
It seems that there were relatively few mothers with uterine irritability in the dataset, only 28. Of those 28, precisely half the babies had low weight, and the rest did not. When we compare these proportions to the rest of the dataset, we see that uterine irritability is definitely associated with low birth rate, although to a lesser degree than hypertension. Babies were almost 1.8 times more likely to be born with low weight if their mother suffered from uterine irritability than babies whose mothers did not.
Task: In the following `R` chunk explore the association between smoking status and whether the babies were born with low birthweight, using both the counts and appropriate percentages. Explain the results in words.
```{r}
lowbwt %>% select(low, smoke) %>% table()
lowbwt %>% select(low, smoke) %>% table() %>% prop.table(margin = 2)
```
Smoking definitely has an association with low birth weight, although to a lesser degree than uterine irritability. Babies of smokers were about 1.6 times more likely than the babies of non-smokers to have low birth rate. However, babies of smokers were more likely to be non-low weight than low weight. There are also a lot more mothers who are smokers than have uterine irritability, so the smoker data should be less sensitive to outliers.
Now we will create some barcharts.
# Barchart of Low Birthweight
The following is a frequency plot of the low birthweight status.
```{r}
ggplot(lowbwt, aes(x = low, fill = low)) +
geom_bar()
```
Task: In the following `R` chunk create a frequency plot of the smoking status.
```{r}
ggplot(lowbwt, aes(x = smoke, fill = smoke)) +
geom_bar()
```
# Stacked Barchart of Low Birthweight by Hypertension Status
Below is a relative frequency plot of the low birthweight of the babies against the hypertension status of the mothers using a stacked barchart.
```{r}
ggplot(lowbwt, aes(x = ht)) +
geom_bar(aes(fill = low), position = "fill") +
ylab("Proportion")
```
Task: Create a stacked barchart of low birthweight by smoking status by inserting an `R` chunk and relevant code below.
```{r}
ggplot(lowbwt, aes(x = smoke)) +
geom_bar(aes(fill = low), position = "fill") +
ylab("Proportion")
```
Task: Create a stacked barchart of low birthweight by uterine irritability by inserting an `R` chunk and relevant code below.
```{r}
ggplot(lowbwt, aes(x = ui)) +
geom_bar(aes(fill = low), position = "fill") +
ylab("Proportion")
```
Task: Once you have created the plots, explain your interpretation of which factors are associated with low birthweight based on the three barcharts. State which factor you think is most associated with birthweight.
Based off of the 3 barcharts, I would say that all 3 factors are associated with low birthweight. It appears to me that hypertension is most associated with low birthweight (0.5833333), followed by uterine irritability (0.5000000), followed by smoke (0.4054054). However, it may be relevant to note that the sample size of each of those factors is rather small, and therefore sensitive to outliers.
The following `R` chunk produces a boxplot of the birthweight distribution.
```{r}
lowbwt %>% ggplot(aes(y = bwt)) +
geom_boxplot() +
labs(y = "Birthweight (in grams)")
```
Task: In the previous task you stated which factor you believe was most associated with birthweight, so you can explore the impact on the distribution in more detail. Create a graph of side-by-side boxplots comparing the birthweight distribution for each level of that factor (e.g. comparing mothers who had uterine irritability and those who did not), by inserting an `R` chunk and relevant code below.
[Hint: we used side-by-side boxplots in the week 4 lab and in the Exploratory Data Analysis worksheet]
```{r}
lowbwt %>% ggplot(aes(y = bwt, x = factor(ht))) +
geom_boxplot() +
labs(x = "ht")
```
# Conclusion
Task: Write a short conclusion of whether you think low birthweight of babies can be predicted based on whether the mother smoked, has hypertension or uterine irritability.
It's clear that there is some association between low birthweight of babies based off whether the mother smoked, had hyptertension, or uterine irritability,
However, it's more difficult to say whether low birthweight can be predicted by any of these factors.
I would say that low birthweight can be predicted by hypertension, as the majority of babies born to mothers with hypertension have low birthrate (0.5833333).
However, uterine irritability is a predictor of an increased chance of low birthweight, but not low birthweight itself. It appears from the data that it is 50-50 (0.5000000) whether a baby born to a mother with uterine irritability will have low birthrate, so you couldn't make an accurate prediction about the baby of a mother with uterine irritability. However, it most certainly does predict increased chances of low birthweight.
Finally, while smoking is a predictor of increased chance of low birthweight (0.4054054), the majority of babies born to smokers do not have low birthweight, which means that the only reasonable prediction you could make about a baby born to a smoker is that it *will not* have a low birthweight, although there is a significant chance that it will, which is significantly higher than the chance of a non-smoker having a baby with low birthweight.
Final Task: "knit" the file as a Word of PDF document and submit it via the relevant link on Blackboard before the deadline.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@ -0,0 +1 @@
{:highlights []}

View File

@ -0,0 +1 @@
{:highlights []}

Some files were not shown because too many files have changed in this diff Show More