cifer-1.2.0/ 0000755 0001750 0001750 00000000000 11156502713 010743 5 ustar ssb ssb cifer-1.2.0/cifer-dict 0000755 0001750 0001750 00000004240 11156502713 012702 0 ustar ssb ssb #!/bin/bash
# Cifer: Automating classical cipher cracking in C
# Copyright (C) 2008 Daniel Richman & Simrun Basuita
#
# Cifer is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Cifer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Cifer. If not, see .
set -e
args=("$@");
[ $# -lt 2 ] && { echo "Usage: cifer-dict indict1 [indict2] ... outdict"; exit 1; }
let OUTFILEN=$#-1
INFILE=0
OUTFILE=${args[$OUTFILEN]}
TMPFILE=/tmp/cifer-dict-tmp
TMPFILE2=/tmp/cifer-dict-tmp2
echo "cifer-dict started with $OUTFILEN infiles... "
echo -n "Clearing Tempfiles... "
echo -n > $TMPFILE
echo -n > $TMPFILE2
echo "Done"
for ((INFILE=0;INFILE<$OUTFILEN;INFILE++)); do
echo -n "Adding ${args[$INFILE]}... "
cat "${args[$INFILE]}" >> $TMPFILE
echo "Done"
ADDED=`wc -l "${args[$INFILE]}" | egrep -o "^[0-9]+"`
RTOTAL=`wc -l "$TMPFILE" | egrep -o "^[0-9]+"`
echo "$ADDED words added, new total $RTOTAL"
done
echo -n "Converting non ascii chars (iconv TRANSLIT)... "
cat $TMPFILE | iconv --from-code ISO_8859-1 --to-code ASCII//TRANSLIT > $TMPFILE2
echo "Done"
echo -n "Stripping non Alpha characters (sed)... "
cat $TMPFILE2 | sed s/[^a-zA-Z]//g > $TMPFILE
echo "Done"
echo -n "Converting to lowercase (dd)... "
dd conv=lcase if=$TMPFILE of=$TMPFILE2 2> /dev/null
echo "Done"
echo -n "Sorting dictionary a-z (sort)... "
cat $TMPFILE2 | sort > $TMPFILE
echo "Done"
echo -n "Removing duplicate entries (uniq)... "
cat $TMPFILE | uniq > $OUTFILE
echo "Done"
OTOT=`wc -l $TMPFILE | egrep -o "^[0-9]+"`
NTOT=`wc -l "$OUTFILE" | egrep -o "^[0-9]+"`
let LOST=$OTOT-$NTOT
echo "$LOST words removed, new total $NTOT"
echo -n "Removing Tmpfiles... "
rm $TMPFILE
rm $TMPFILE2
echo "Done"
echo cifer-dict finished
cifer-1.2.0/README 0000644 0001750 0001750 00000005221 11156502713 011623 0 ustar ssb ssb ===============================================================================
LEGAL
===============================================================================
Cifer is Copyright (C) 2008 Simrun Basuita & Daniel Richman
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
===============================================================================
AUTHORS
===============================================================================
Cifer was written by:
Simrun Basuita
Daniel Richman
Feel free to mail us with bugs, feature requests, or even if you found our
software useful! It's always nice to know that our hard work has helped
somebody out ;)
===============================================================================
INFO
===============================================================================
Cifer provides many functions designed to aid in cracking classical
ciphers; a group of ciphers used historically, but which have now
fallen into disuse because of their suceptability to ciphertext-only
attacks. In general, they were designed and implemented by hand, and
operate on an alphabet of letters (such as [A-Z]).
It operates using text files as input and output, and can perform both brute
force and other, more sophisticated, attacks against many classic encryption
schemes. In addition, it provides many utilities such as frequency analysis
and automated encryption/decryption of texts.
For more information, view the manpages:
$ man manpages/cifer.1
$ man manpages/cifer-dict.1
===============================================================================
INSTALLATION
===============================================================================
You must have libreadline installed prior to building cifer. For example, on
Debian systems:
$ sudo apt-get install libreadline5
Quick start:
$ make -B CFLAGS=-O2 all
$ sudo make install
For more detailed instructions on building, installing, cleaning and other
Makefile usage, see the file INSTALL.
===============================================================================
cifer-1.2.0/VERSION 0000644 0001750 0001750 00000000006 11156502713 012007 0 ustar ssb ssb 1.2.0
cifer-1.2.0/INSTALL 0000644 0001750 0001750 00000006557 11156502713 012011 0 ustar ssb ssb ===============================================================================
INSTALLATION
===============================================================================
You must have libreadline installed on your system prior to building/using
cifer. For example, on Debian systems:
$ sudo apt-get install libreadline5
Quick start:
$ make -B CFLAGS=-O2 all
$ sudo make install # (optional)
Detailed instructions:
1) Build cifer. You can specify extra arguments for gcc by setting the variable
`CFLAGS'. We recommend you use the `-O2' option to enable optimisation.
$ make -B CFLAGS=-O2 all
The -B option ensures that every single object file is rebuilt. In normal
operation, make only rebuilds object files (*.o) when the source files
(*.c and *.h) change. To clean up any possible problems, we reccomend
that -B is used.
2) Install cifer (optional). This requires root privileges. Note that if the
cifer binary does not already exist, it will be automatically built.
The easiest way to install is by simply calling make with the `install'
target:
# make install
You can set the variables `DESTDIR' and/or `prefix' to change the
directories in which the files will be installed. `DESTDIR' specifies the
directory that should be treated as the `root', ie. all files will be
installed underneath it. `prefix' specifies the location underneath the
`root' in which the files will be installed. By default, this is
`/usr/local'. This is best explained with an example:
# make prefix=/usr install
This will install all files to `/usr/bin/*' and `/usr/share/*'. Another
example:
# make DESTDIR=/home/me/stuff/cifer install
This will install all files to `/home/me/stuff/cifer/usr/bin/*' and
`/home/me/stuff/cifer/usr/share/*'. Finally, you can combine the two for
total control (read: "world domination" ;D):
# make prefix=/usr DESTDIR=/var/cifer install
This will install all files to `/var/cifer/usr/bin/*' and
`/var/cifer/usr/share/*'.
===============================================================================
UNINSTALLATION
===============================================================================
Quick start (end):
$ sudo make uninstall
Detailed instructions:
You can uninstall cifer by calling `make' with the `uninstall' target:
# make uninstall
If you changed the values of `prefix' or `DESTDIR' when you installed cifer
(see above) then you must provide the same values when you uninstall. For
example:
# make prefix=/usr DESTDIR=/home/me/stuff/cifer uninstall
===============================================================================
CLEANING
===============================================================================
Quick start:
$ make distclean
Detailed instructions:
After building cifer, you will be left with a binary, and lots of object files
in the src/ directory. If you build again, make should only build source files
that have changed, however, if you would like to just clean up, you can get
rid of those by calling `make' with the target `clean' or `distclean'.
If you would like to change CFLAGS, you _MUST_ clean before rebuilding as
make will not notice the change, otherwise.
Note that `clean' and `distclean' both do exactly the same thing, we just
provide two different names to conform to Makefile standards.
$ make clean OR $ make distclean
cifer-1.2.0/AUTHORS 0000644 0001750 0001750 00000000144 11156502713 012012 0 ustar ssb ssb Simrun Basuita
Daniel Richman
cifer-1.2.0/manpages/ 0000755 0001750 0001750 00000000000 11156502713 012536 5 ustar ssb ssb cifer-1.2.0/manpages/cifer-dict.1 0000644 0001750 0001750 00000003436 11156502713 014637 0 ustar ssb ssb .TH CIFER-DICT 1
.SH NAME
cifer-dict \- turn files containing lists of words into a dictionary for
.BR cifer (1)
.SH SYNOPSIS
\fBcifer-dict\fR \fIinput1\fR [\fIinput2\fR]... \fIoutput\fR
.SH DESCRIPTION
In order to use some functions of \fBcifer\fR(1),
a specially formatted 'dictionary' must be supplied. \fBcifer-dict\fR
takes files containing lists of words as arguments, and outputs the correctly
formatted dictionary.
.PP
This dictionary will have unicode characters converted to their nearest
ASCII equivalents and all characters converted to lower case. It will be sorted
and duplicates removed.
.SH EXAMPLES
\fBcifer-dict /usr/share/dict/words dict\fR
.PP
This uses \fI/usr/share/dict/words\fR as the input list and creates the
formatted dictionary as \fIdict\fR.
.PP
\fBcifer-dict /usr/share/dict/words /home/superman/mywords dictionary\fR
.PP
This uses \fI/usr/share/dict/words\fR and \fI/home/superman/mywords\fR as input
lists and creates the formatted dictionary as \fIdictionary\fR.
.SH BUGS
Please report any bugs by sending email to either
or .
.SH AUTHORS
Daniel Richman ,
Simrun Basuita
.SH COPYRIGHT
This manual page is Copyright 2008 Simrun Basuita and Daniel Richman.
.PP
This manual page was written by Simrun Basuita
and Daniel Richman .
Permission is granted to copy, distribute and/or modify this document under the
terms of the GNU General Public License, Version 3 or any later version
published by the Free Software Foundation.
.PP
On Debian systems, the complete text of the GNU General Public License can be
found in \fI/usr/share/common-licenses/GPL\fR.
.SH "SEE ALSO"
.BR cifer (1)
cifer-1.2.0/manpages/cifer.1 0000644 0001750 0001750 00000024567 11156502713 013726 0 ustar ssb ssb .TH CIFER 1
.SH NAME
cifer \- multipurpose classical cryptanalysis and code\(hybreaking tool
.SH SYNOPSIS
\fBcifer\fR [\-finqs] [command]
.SH DESCRIPTION
\fBCifer\fR provides many functions designed to aid in cracking classical
ciphers; a group of ciphers used historically, but which
have now fallen into disuse because of their suceptability to
ciphertext\(hyonly
attacks. In general, they were designed and implemented by hand, and operate
on an alphabet of letters (such as [A\(hyZ]).
.PP
\fBCifer\fR is implemented as an interactive shell, with support for scripting.
All of its commands are documented via the \fBusage\fR command. For instance,
type \fBusage load_dict\fR for information on the \fBload_dict\fR command.
.SS Buffers and Filters
The shell uses the concept of a \fBbuffer\fR to store a string of text, which
most comands read from as input, and write to as output. Unless run with the
\fB\-n\fR option, \fBcifer\fR will automatically create 10 buffers at startup.
Buffers are referred to in the form, \fBbuffer_#\fR, where \fB#\fR is
substituted with the buffer's index number. For more information on buffers,
see the \fBusage\fR for:
.BR buffers ,
.BR resize ,
.BR clear ,
.BR copy ,
.BR load ,
.BR write ,
.BR read ,
.BR bufferinfo ", and"
.BR nullbuffer .
.PP
Filters can be used to manipulate the set of characters in a buffer, for
example making all characters uppercase, or removing all whitespace. For more
information on filters, see the \fBusage\fR of \fBfilter\fR.
.SS Dictionaries
Some of \fBcifer\fR's functions require a specially formatted 'dictionary',
which takes the basic form of a list of words. The utility \fBcifer\-dict\fR(1)
can be used to create these dictionaries. The \fBloaddict\fR command is used
to load a dictionary for use.
.SS Frequency Analysis
Frequency analysis is the study of the frequency of symbols, or groups of
symbols in a ciphertext. It aids in cracking monoalphabetic substition schemes.
Frequency analysis works upon the principle that, in any given sample of
written language, certain characters and groups of characters will occur more
often than others. Furthermore, the distribution of those frequencies will be
roughly the same for all samples of that written language. For instance, in any
section of English language, the character 'E' appears far more often than 'X'.
Likewise, the pair of letters 'TH' is very common, whilst 'XY' is very rare. In
monoalphabetic substitution schemes, these patterns are preserved and it is
possible to determine certain mapppings of letters from
ciphertext\(hy>plaintext
from the frequencies alone. As more and more characters are converted, it
becomes easy to guess the remaining ones to form words in the target language.
.PP
Perhaps the most tedious part of this method is the actual counting of the
symbols themselves. Thus, \fBCifer\fR provides functions to count characters,
digrams (pairs of characters), and trigrams (triplets of characters). It can
also use frequency analyis to guess ciphertext\(hy>plaintext mappings for the
English language. For more information, see the \fBusage\fR for:
.BR frequency_guesses ,
.BR identity_frequency_graph ,
.BR frequency_analysis ,
.BR count_digrams ", and"
.BR count_trigrams .
.SS Affine Ciphers
An affine cipher is a type of monoalphabetic substitution cipher. In order to
implement an affine cipher, one would assign each character of the chosen
alphabet a number, for example, a = 0; b = 1; c = 2; etc. Then for each letter
of the plaintext, put it through the encryption function:
.PP
.B e(x) = (ax + b) (mod m)
.PP
Where \fBx\fR is the plaintext character's assigned number, \fBa\fR and \fBm\fR
are coprime and \fBm\fR is the size of the alphabet. The ciphertext character
for this plaintext character is the character assigned to the number
\fBe(x)\fR.
.PP
Cifer provides functions to both encrypt and decrypt affine ciphers as well
as crack affine ciphers using frequency analysis or brute force. Note that
cifer is currently only able to deal with affine ciphers where \fBm = 26\fR.
For more information, see the \fBusage\fR for:
.BR affinesolve ,
.BR affinebf ,
.BR affineencode ,
.BR affinedecode ", and"
.BR mmi .
.SS Vigenere Ciphers
The Vigenere cipher is a form of polyalphabetic substitution consisting of
several Caesar ciphers in sequence with differing shift values, which vary
according to a repeating keyword. \fBCifer\fR provides the function
\fBvigenere_crack\fR, which employs a brute\(hyforce (for each possible keyword
length) frequency analysis method in order to find the keyword, and crack the
cipher.
.SS Keyword Ciphers
A keyword cipher is a type of monoalphabetic substitution in which the mapping
of plaintext characters to ciphertext characters is affected by the inclusion
of a 'keyword'. \fBCifer\fR provides the function \fBkeyword_bruteforce\fR
which attempts to find the correct keyword by going through a 'dictionary' of
possible words and trying each one in turn, then selecting the best solution
by matching words in the solution to those in the dictionary. If the keyword
to a ciphertext is already known, it can be decoded using the
\fBkeyword_decode\fR command.
.SS Bacon Ciphers
A bacon cipher is a method of stenography, in which a message is concealed in
the presentation of text, rather than its content. The ciphertext consists of
any message (again, the language has no impact on the concealed plaintext) in
which each character can be categorised into one of two distinct groups, we call
these 'A' and 'B'. This distinction may be made in any number of predetermined
ways, such as two typefaces, or other indicators. In order to decode the cipher
one replaces groups of 5 As and Bs with their corresponding plaintext character,
as dictated by the Baconian alphabet (however, be aware that it would be
trivial for the two communicating parties to create their own 'custom' version
of the Baconian alphabet). To encode a plaintext, the reverse operation is
performed.
.PP
A Bacon cipher can be easily encoded/decoded, and \fBcifer\fR provides the
functions \fBbacon_encode\fR and \fBbacon_decode\fR to achieve this. They use
a buffer of As and Bs as input and output, and thus any ciphertext that needs
to be decoded must first be turned into As and Bs. Before the plaintext is
loaded, it should be modified so that upper and lower case characters
belong to the A and B groups, respectively. Then, the \fBcasebacon\fR filter
can be applied to convert the upper and lower case characters in the buffer
to As and Bs. There is also a \fBbacon\fR filter, which removes all characters
which are not 'A' or 'B'.
.SS Rail Fence Ciphers
The rail fence cipher is a form of transposition cipher, which gets its name
from the way the plaintext is written alternatively downwards and upwards
diagonally on 'rails', before being read off as the ciphertext in rows.
.PP
\fBCifer\fR provides the function \fBrfbf\fR to crack rail fence ciphers using
a brute force method and checking for solutions using a dictionary.
.SS Columnar Transposition
Columnar transposition is a relatively complex form of cipher, with many
variants. The basic process of encoding using this method involves first
writing the plaintext out in a table defined by its width (which is also the
length of the keyword). Then, depending on the variant, the ciphertext is
written and read out of the table in any number of different ways.
.PP
The keyword can be specified in numeric or alphabetic form. In the former, each
digit must only be used once and there must be enough digits to form a full
key (ie. for a key length 4, all the digits [0,1,2,3] must be used). An
alphabetic keyword, such as 'apple', first has duplicate letters removed. This
gives us 'aple'. If you were encrypting by hand, you would write out 'aple'
at the top of your table, and them move the columns around until the keyword
is in alphabetic order, ie. 'aelp'.
.PP
In order to decrypt a ciphertext, we first 'flip' the keyword, turning 'aelp'
into 'plea'. We can then use this keyword as if we were encrypting, and the
process will reverse the original function to give us the plaintext.
.PP
\fBCifer\fR's keyword functions provide utilities to automate many variants.
There are nine commands: \fBc2c_encode\fR, \fBc2c_decode\fR,
\fBc2c_bruteforce\fR, \fBr2c_encode\fR, \fBr2c_decode\fR, \fBr2c_bruteforce\fR,
\fBc2r_encode\fR, \fBc2r_decode\fR and \fBc2r_bruteforce\fR.
.PP
The first three letters of each command are short for: 'column to column',
\'column to row' and 'row to column'; these refer to different ways in
which the ciphertext can be read off the table. In \fBc2c\fR, the table is
written from
left to right, re\(hyordered and read off left to right again. In \fBr2c\fR,
the
table is written from top to bottom, re\(hyordered and then read off from left
to
right. Finally, in
\fBc2r\fR the table is written left to right, re\(hyordered and read off from
top
to bottom.
.PP
\'Encode' and 'decode' mode both take a keyword and work as one would expect.
In 'bruteforce' mode, \fBcifer\fR tries all permutations of increasing key
lengths in an attempt to find the real keyword. It tests possible solutions by
matching words in the dictionary.
.SH OPTIONS
.TP
.BR \-n
Disable auto-init.
.TP
.BR \-f
Execute the commands in the (script) file specified, then exit
.TP
.BR \-i
Execute the script file and then go to interactive mode
.TP
.BR \-q
Do not fully parse file before execution
.TP
.BR \-s
Exit on soft-fails, not just hard-fails (for script execution)
.PP
Any text found after the options will be interpreted as a command to the shell;
Please note that you cannot specify a command if either \fB\-i\fR or \fB\-f\fR
are used, and that \fB\-q\fR and \fB\-s\fR only apply to \fB\-f\fR or \fB\-i\fR.
.SH BUGS
Please report any bugs by sending email to either Simrun Basuita
or Daniel Richman
.
.SH AUTHORS
Daniel Richman ,
Simrun Basuita
.SH COPYRIGHT
This manual page is Copyright 2008 Simrun Basuita and Daniel Richman.
.PP
This manual page was written by Simrun Basuita
and Daniel Richman .
Permission is granted to copy, distribute and/or modify this document under the
terms of the GNU General Public License, Version 3 or any later version
published by the Free Software Foundation.
.PP
On Debian systems, the complete text of the GNU General Public License can be
found in \fI/usr/share/common\-licenses/GPL\fR.
.SH "SEE ALSO"
.BR cifer\-dict (1)
cifer-1.2.0/COPYING 0000644 0001750 0001750 00000104374 11156502713 012007 0 ustar ssb ssb
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
cifer-1.2.0/CHANGES 0000644 0001750 0001750 00000003447 11156502713 011746 0 ustar ssb ssb # 1.2.0 ##################################### Tue, 10 Mar 2009 19:59:44 +0000 #
* Added more buffer-type checkes, and input file checks to ensure
smooth operation
* Fixed a bug which occured when trying to read in a special/block file
###############################################################################
# 1.1.0 ##################################### Wed, 17 Dec 2008 20:20:56 +0000 #
* `More' style support added to the help action, multiple pages.
* libreadline support added
###############################################################################
# 1.0.4 ##################################### Mon, 15 Dec 2008 17:23:20 +0000 #
* Binaries are no longer stripped by the make install target
* We no longer use the Makefile variable CFLAGS_EXTRA
###############################################################################
# 1.0.3 ##################################### Sun, 07 Dec 2008 12:51:15 +0000 #
* manpages/cifer.1 now uses correct syntax for hyphens vs minus signs
* The cifer binary is now stripped more thoroughly when installed
###############################################################################
# 1.0.2 ##################################### Fri, 05 Dec 2008 17:21:18 +0000 #
* Removed debian/ directory as it was making life harder for downstream
distros
###############################################################################
# 1.0.1 ##################################### Sat, 29 Nov 2008 19:48:30 +0000 #
* Release 1.0.0 had .svn folders :O !!! (forgot to export)
###############################################################################
# 1.0.0 ##################################### Sat, 29 Nov 2008 19:47:58 +0000 #
* Initial release!
###############################################################################
cifer-1.2.0/Makefile 0000644 0001750 0001750 00000005466 11156502713 012416 0 ustar ssb ssb #!/usr/bin/make -f
# -*- makefile -*-
# Cifer: Automating classical cipher cracking in C
# Copyright (C) 2008 Daniel Richman & Simrun Basuita
#
# Cifer is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Cifer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Cifer. If not, see .
SHELL = /bin/sh
version := $(shell cat VERSION)
CC = gcc
CFLAGS = -Wall -pedantic
DEFS = -DVERSION="\"$(version)\""
LINKLIBS = -lreadline
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
datarootdir = $(prefix)/share
mandir = $(datarootdir)/man
man1dir = $(mandir)/man1
INSTALL = install
INSTALL_PROGRAM = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644
INSTALL_DIR = $(INSTALL) -d
srcmandir = manpages/
rm = rm -f
rmdir = rm -rf
mkdir = mkdir -p
cfiles := $(wildcard src/*.c)
objects := $(patsubst %.c,%.o,$(cfiles))
headers := $(wildcard src/*.h src/*.inc)
allfiles := $(wildcard *)
all : cifer
cifer : $(objects)
$(CC) $(CFLAGS) $(LINKLIBS) -o $@ $(objects)
src/%.o : src/%.c $(headers)
$(CC) $(DEFS) -c $(CFLAGS) $< -o $@
.PHONY : all \
\
install \
install-man \
install-bin \
install-dir-man \
install-dir-bin \
\
uninstall \
uninstall-man \
uinstall-bin \
\
clean \
distclean \
\
dist
install : install-man install-bin
install-dir-man :
[ -d $(DESTDIR)$(man1dir) ] || $(INSTALL_DIR) $(DESTDIR)$(man1dir)
install-dir-bin :
[ -d $(DESTDIR)$(bindir) ] || $(INSTALL_DIR) $(DESTDIR)$(bindir)
install-man : install-dir-man
$(INSTALL_DATA) $(srcmandir)/cifer.1 \
$(DESTDIR)$(man1dir)/cifer.1
$(INSTALL_DATA) $(srcmandir)/cifer-dict.1 \
$(DESTDIR)$(man1dir)/cifer-dict.1
install-bin : all install-dir-bin
$(INSTALL_PROGRAM) cifer $(DESTDIR)$(bindir)/cifer
$(INSTALL_PROGRAM) cifer-dict $(DESTDIR)$(bindir)/cifer-dict
uninstall: uninstall-man uninstall-bin
uninstall-man :
$(rm) $(DESTDIR)$(man1dir)/cifer.1
$(rm) $(DESTDIR)$(man1dir)/cifer-dict.1
uninstall-bin :
$(rm) $(DESTDIR)$(bindir)/cifer
$(rm) $(DESTDIR)$(bindir)/cifer-dict
clean :
$(rm) cifer $(objects)
distclean : clean
dist : clean
$(mkdir) cifer-$(version)
for i in $(allfiles); do \
cp --recursive $$i cifer-$(version); \
done
$(rmdir) cifer-$(version)/copy-header \
cifer-$(version)/notes \
cifer-$(version)/tests
tar cf - cifer-$(version) | \
gzip -9f > \
cifer-$(version).tar.gz
$(rmdir) cifer-$(version)
cifer-1.2.0/src/ 0000755 0001750 0001750 00000000000 11156502713 011532 5 ustar ssb ssb cifer-1.2.0/src/io.h 0000644 0001750 0001750 00000005161 11156502713 012315 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define CFSH_IO_MODE_AUTO 0 /* Create the file if it doesnt exist */
#define CFSH_IO_MODE_OVERWRITE 1 /* Overwrite or create */
#define CFSH_IO_MODE_APPEND 2 /* Append or create */
#define BUFFER_FILTER_NONE 4 /* No filter applied yet */
#define BUFFER_FILTER_ALPHA 5 /* Alpha only, case preserved */
#define BUFFER_FILTER_ALPHANUM 6 /* Alphanumeric only */
#define BUFFER_FILTER_LALPHA 7 /* Alpha only, All lower */
#define BUFFER_FILTER_UALPHA 8 /* Alpha only, All upper */
#define BUFFER_FILTER_FLIPCASE 9 /* Flip Case */
#define BUFFER_FILTER_CASEBACON 10 /* Changes case to ab */
#define BUFFER_FILTER_BACON 11 /* Filters to AB only */
#define BUFFER_FILTER_NUM 12 /* Numbers only */
#define BUFFER_FILTER_ESP 13 /* All but spaces & xsp chars */
#define BUFFER_FILTER_ENL 14 /* All but xsp chars (see macros) */
extern char **cfsh_buffers;
extern int *cfsh_buffer_filters;
extern int *cfsh_buffer_sizes;
extern int cfsh_num_buffers;
void buffers_init();
void create_buffers(int num);
void size_buffer_array(int num);
void file2buffer(char *name, int buffer_id);
void buffer2file(char *name, int buffer_id, int mode);
void initbuffer(int buffer_id);
void destroybuffer(int buffer_id);
void resizebuffer(int buffer_id, int newsize);
void copybuffer(int buffer_id_1, int buffer_id_2);
void filterbuffer(int buffer_id, int mode);
void clearbuffer(int buffer_id);
int get_buffer_real_size(int buffer_id);
int get_buffer_filter_fromtext(char *str);
char *get_filter_text(int mode);
#define get_buffer(i) (*(cfsh_buffers + i))
#define get_buffer_filter(i) (*(cfsh_buffer_filters + i))
#define get_buffer_filter_text(i) get_filter_text(get_buffer_filter(i))
#define get_buffer_size(i) (*(cfsh_buffer_sizes + i))
#define setbuffernull(i) (*(get_buffer(i) + get_buffer_size(i)) = 0)
cifer-1.2.0/src/command.c 0000644 0001750 0001750 00000016326 11156502713 013324 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
int cfsh_parse(char *input, cfsh_execinfo *execinfo)
{
/* Parse string line into argc and argv */
int i, j, size, spacing, had_char, had_command, quote, escaping;
char *input_mark, *input_end, *command;
char ch;
execinfo->argv = NULL;
execinfo->command = NULL;
execinfo->argc = 0;
spacing = 0;
had_char = 0;
had_command = 0;
quote = 0;
escaping = 0;
command = NULL;
size = strlen(input);
input_end = input + size;
/* Pass 1: count the number of arguments and filter bad, nasty characters */
for (input_mark = input; input_mark < input_end; input_mark++)
{
ch = (char) *input_mark;
if (escaping == 0 && quote == 0 && (SPACE_CH(ch) || XSPACE_CH(ch)))
{
if (!spacing && had_char)
{
if (had_command) (execinfo->argc)++;
else had_command = 1;
spacing = 1; /* Catch multiple spaces */
}
}
else if (escaping == 0 && quote == 0 && QUOTE_CH(ch))
{
quote = ch;
}
else if (escaping == 0 && ch == quote)
{
if (!had_char)
{
return CFSH_PARSE_EMPTY;
}
else
{
if (had_command) (execinfo->argc)++;
else had_command = 1;
spacing = 1;
}
quote = 0;
}
else if (escaping == 0 && ESCAPE_CH(ch))
{
escaping = 1;
}
else if (escaping && !ESCAPE_CH(ch) && !SPACE_CH(ch) &&
!XSPACE_CH(ch) && !QUOTE_CH(ch))
{
return CFSH_PARSE_EBAD;
}
else
{
spacing = 0;
had_char = 1;
escaping = 0;
}
}
/* And anything left over... */
if (!spacing && had_char)
{
if (had_command) (execinfo->argc)++;
else had_command = 1;
}
if (!had_command) return CFSH_PARSE_EMPTY;
if (quote != 0) return CFSH_PARSE_QUOTEOPEN;
if (escaping) return CFSH_PARSE_EBAD;
/* Allocate... */
if (execinfo->argc != 0)
execinfo->argv = malloc_good( sizeof(char *) * (execinfo->argc) );
/* Pass 2: Allocate correct lengths! */
execinfo->argc = 0;
spacing = 0;
had_char = 0;
had_command = 0;
quote = 0;
escaping = 0;
j = 0;
for (input_mark = input; input_mark < input_end; input_mark++)
{
ch = (char) *input_mark;
if (escaping == 0 && quote == 0 && (SPACE_CH(ch) || XSPACE_CH(ch)))
{
if (!spacing && had_char)
{
if (had_command)
{
*((execinfo->argv) + (execinfo->argc)) = malloc_good( j + 1 );
(execinfo->argc)++;
}
else
{
command = malloc_good( j + 1 );
had_command = 1;
}
spacing = 1; /* Catch multiple spaces */
j = 0;
}
}
else if (escaping == 0 && quote == 0 && QUOTE_CH(ch))
{
quote = ch;
}
else if (escaping == 0 && ch == quote)
{
if (had_command)
{
*((execinfo->argv) + (execinfo->argc)) = malloc_good( j + 1 );
(execinfo->argc)++;
}
else
{
command = malloc_good( j + 1 );
had_command = 1;
}
spacing = 1;
quote = 0;
j = 0;
}
else if (escaping == 0 && ESCAPE_CH(ch))
{
escaping = 1;
}
else
{
spacing = 0;
had_char = 1;
escaping = 0;
j++;
}
}
/* And any final left over... */
if (!spacing && had_char)
{
if (had_command)
{
*((execinfo->argv) + (execinfo->argc)) = malloc_good( j + 1 );
(execinfo->argc)++; j = 0;
}
else
{
command = malloc_good( j + 1 );
had_command = 1; j = 0;
}
spacing = 1; /* Catch multiple spaces */
}
/* Pass 3: Load up the values! */
execinfo->argc = 0;
spacing = 0;
had_char = 0;
had_command = 0;
quote = 0;
escaping = 0;
j = 0;
for (input_mark = input; input_mark < input_end; input_mark++)
{
ch = (char) *input_mark;
if (escaping == 0 && quote == 0 && (SPACE_CH(ch) || XSPACE_CH(ch)))
{
if (!spacing && had_char)
{
if (had_command)
{
*( *((execinfo->argv) + execinfo->argc) + j ) = 0;
(execinfo->argc)++;
}
else
{
*( command + j ) = 0;
had_command = 1;
}
spacing = 1; /* Catch multiple spaces */
j = 0;
}
}
else if (escaping == 0 && quote == 0 && QUOTE_CH(ch))
{
quote = ch;
}
else if (escaping == 0 && ch == quote)
{
if (had_command)
{
*( *((execinfo->argv) + execinfo->argc) + j ) = 0;
(execinfo->argc)++;
}
else
{
*( command + j ) = 0;
had_command = 1;
}
j = 0;
spacing = 1;
quote = 0;
}
else if (escaping == 0 && ESCAPE_CH(ch))
{
escaping = 1;
}
else
{
spacing = 0;
had_char = 1;
escaping = 0;
if (had_command) *( *((execinfo->argv) + execinfo->argc) + j ) = ch;
else *( command + j ) = ch;
j++;
}
}
if (!spacing && had_char)
{
if (had_command)
{
*( *((execinfo->argv) + execinfo->argc) + j ) = 0;
(execinfo->argc)++;
}
else
{
*( command + j ) = 0;
had_command = 1;
}
}
i = cfsh_get_func(command, &(execinfo->command));
free(command);
if (i == CFSH_FUNC_OK)
{
return CFSH_PARSE_OK;
}
else
{
cfsh_free_execinfo(execinfo);
return i;
}
}
void cfsh_free_execinfo(cfsh_execinfo *execinfo)
{
int i;
for (i = 0; i < (execinfo->argc); i++) free(*((execinfo->argv) + i));
if (execinfo->argc != 0) free(execinfo->argv);
}
#define cfsh_func(n, f) if (strcasecmp(n, name) == 0) \
{ *command = &f; return CFSH_FUNC_OK; }
int cfsh_get_func(char *name, cfsh_command *command)
{
#include "command.inc"
/* Else... */
return CFSH_FUNC_NOEXIST;
}
#undef cfsh_func
#define cfsh_func(n, f) if (strcasecmp(n, name) == 0) \
{ return f ## _usage; }
char *cfsh_get_usage(char *name)
{
#include "command.inc"
return action_default_usage;
}
#undef cfsh_func
#define cfsh_func(n, f) if (strcasecmp(n, name) == 0) \
{ return f ## _use; }
char *cfsh_get_use(char *name)
{
#include "command.inc"
return action_default_use;
}
#undef cfsh_func
cifer-1.2.0/src/main.c 0000644 0001750 0001750 00000010216 11156502713 012622 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
int main(int argc, char **argv)
{
/* Take a look at argc & argv.
* If argc == 0; go to interatcive mode (shell.c)
* else, first look for switches:
* -n disables auto-init
* -i means that the file should be executed THEN go to interactive
* -f is a synonym for just using the script instruction on its own
* -q means that any file executed shouldn't be wholly parsed first
* -s means that soft-fails will cause an exit, not just hard-fails
* then treat the rest as a shell command. */
int i, j, noauto, init, file, quick, soft, mute;
cfsh_execinfo execinfo;
noauto = 0;
init = 0;
file = 0;
quick = 0;
soft = 0;
mute = 0;
/* Unavoidable startup. Initialises global pointers and sets
* default dictionary location */
cfsh_init();
if (argc < 2)
{
cfsh_autoinit();
return cfsh_interactive();
}
else
{
/* Are there any sqitches? */
if (**(argv + 1) == '-') /* First char of first arg. */
{
for (i = 1; i < strlen(*(argv + 1)); i++) switch (*(*(argv + 1) + i))
{
case 'n': noauto = 1; break;
case 'i': init = 1; break;
case 'f': file = 1; break;
case 'q': quick = 1; break;
case 's': soft = 1; break;
case 'm': mute = 1 ; break;
default : printf("Unrecognised switch %c.\n",
(*(*(argv + 1) + i)));
return 1; break;
}
}
if ((init || file) && argc > 3)
{
printf("cifer (main): trailing arguments.\n");
return 1;
}
if ((quick || soft) && !(init || file))
{
printf("cifer (main): quick|soft can only be used with init|file.\n");
return 1;
}
if (mute && !file)
{
printf("cifer (main): mute can only be used with file.\n");
return 1;
}
if (init && file)
{
printf("cifer (main): init cannot be used in conjection with file.\n");
return 1;
}
/* Depending on if there were switches or not, where do args start ? */
i = (**(argv + 1) == '-' ? 3 : 2);
if (init || file)
{
if (argc < 3)
{
printf("cifer (main): please specify a file.\n");
return 1;
}
if (file) close(0); /* Input not needed */
if (mute) close(1); /* Stop any output to stdout */
if (!noauto) cfsh_autoinit();
cfsh_scriptfile(*(argv + 2), !quick, soft);
if (init) cfsh_interactive();
}
else if (argc > i - 1)
{
if (!noauto) cfsh_autoinit();
execinfo.argc = argc - i;
if (execinfo.argc != 0)
execinfo.argv = malloc_good( sizeof(char *) * execinfo.argc );
else
execinfo.argv = NULL;
if (cfsh_get_func(*(argv + i - 1), &execinfo.command)
== CFSH_FUNC_NOEXIST)
{
printf("cifer (main): command does not exist.\n");
return 1;
}
for (j = 0; j < execinfo.argc; j++)
*(execinfo.argv + j) = *(argv + j + i);
return cfsh_exec(execinfo);
}
else
{
if (!noauto) cfsh_autoinit();
return cfsh_interactive();
}
}
return 0; /* This should return whatever shell.c ends up with */
}
cifer-1.2.0/src/actions.h 0000644 0001750 0001750 00000011226 11156502713 013345 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
/* typedef int(*cfsh_command)(int argc, char **argv);
*
* CFSH_OK 0
* CFSH_BREAK_LOOP 99 */
/* TODO: Fix argv. We should really put the command name in [0] and then
* start at [1]. */
/* TODO: better _system tact */
/* TODO: Proper Preparsing */
#include "actions_macros.h"
int actionu_intparse_f(char *str, int *value, int char_mode, void *failfree);
int actionu_bufferparse_f(char *str);
int actionu_bufferchk_f(int buffer_in, int buffer_out);
int actionu_bufferfchk_f(int buffer_id, int filter);
void actionu_bufferschk(int buffer_id, int buffer_out);
void actionu_copysize(int buffer_in, int buffer_out);
int actionu_ctrans_keyword_parse(int argc, char **argv,
int **key, int *key_size);
int actionu_ctrans_default(int argc, char **argv,
int flip, char *dirstring, char *typestring,
columnar_transposition_function routine);
int actionu_ctrans_bruteforce(int argc, char **argv,
columnar_transposition_function routine);
int action_buffers(int argc, char **argv);
int action_quit(int argc, char **argv);
int action_resize(int argc, char **argv);
int action_clear(int argc, char **argv);
int action_copy(int argc, char **argv);
int action_load(int argc, char **argv);
int action_write(int argc, char **argv);
int action_filter(int argc, char **argv);
int action_read(int argc, char **argv);
int action_bufferinfo(int argc, char **argv);
int action_nullbuffer(int argc, char **argv);
int action_script(int argc, char **argv);
int action_quickscript(int argc, char **argv);
int action_softscript(int argc, char **argv);
int action_quicksoftscript(int argc, char **argv);
int action_loaddict(int argc, char **argv);
int action_score(int argc, char **argv);
int action_spaces(int argc, char **argv);
int action_wordwrap(int argc, char **argv);
int action_affine(int argc, char **argv);
int action_affinesolve(int argc, char **argv);
int action_affinebf(int argc, char **argv);
int action_affineencode(int argc, char **argv);
int action_affinedecode(int argc, char **argv);
int action_baconencode(int argc, char **argv);
int action_bacondecode(int argc, char **argv);
int action_shift(int argc, char **argv);
int action_deltaic(int argc, char **argv);
int action_monoalph(int argc, char **argv);
int action_ctrans_keyinfo(int argc, char **argv);
int action_c2c_encode(int argc, char **argv);
int action_c2c_decode(int argc, char **argv);
int action_c2c_bruteforce(int argc, char **argv);
int action_r2c_encode(int argc, char **argv);
int action_r2c_decode(int argc, char **argv);
int action_r2c_bruteforce(int argc, char **argv);
int action_c2r_encode(int argc, char **argv);
int action_c2r_decode(int argc, char **argv);
int action_c2r_bruteforce(int argc, char **argv);
int action_fg(int argc, char **argv);
int action_ifg(int argc, char **argv);
int action_fa(int argc, char **argv);
int action_digrams(int argc, char **argv);
int action_trigrams(int argc, char **argv);
int action_pct(int argc, char **argv);
int action_keyb(int argc, char **argv);
int action_keye(int argc, char **argv);
int action_keyd(int argc, char **argv);
int action_keyt(int argc, char **argv);
int action_keytf(int argc, char **argv);
int action_polybius_encode(int argc, char **argv);
int action_polybius_decode(int argc, char **argv);
int action_rfbf(int argc, char **argv);
int action_vigenere(int argc, char **argv);
int action_mmi(int argc, char **argv);
int action_gcd(int argc, char **argv);
int action_coprime(int argc, char **argv);
int action_charinfo(int argc, char **argv);
int action_usage(int argc, char **argv);
void action_help_lnblk(int *lnc, int nln);
void action_help_strpr(char *str, int *lnc, int nln);
void action_help_nl(int *lnc, int nln);
int action_help(int argc, char **argv);
int action_system(int argc, char **argv);
int action_cd(int argc, char **argv);
int action_ls(int argc, char **argv);
/* int action_(int argc, char **argv); */
cifer-1.2.0/src/ciphers.c 0000644 0001750 0001750 00000003441 11156502713 013335 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
void monoalph_substitute(char *intext, int intext_size, char *outtext,
int *translation)
{
int i;
char ch;
for (i = 0; i < intext_size; i++)
{
ch = *(intext + i);
*(outtext + i) = ALPHA_CH(ch) ? NUMCHAR(translation[CHARNUM(ch)]) : ch;
}
}
void caesar_cipher_enc(char *intext, int intext_size, char *outtext,
int *shift, int shift_size)
{
int i;
char ch;
for (i = 0; i < intext_size; i++)
{
ch = *(intext + i);
*(outtext + i) = ALPHA_CH(ch) ? NUMCHAR( modn( CHARNUM(ch) +
*(shift + modp(i, shift_size)), 26) ) : ch;
}
}
void caesar_cipher_dec(char *intext, int intext_size, char *outtext,
int *shift, int shift_size)
{
int i;
char ch;
for (i = 0; i < intext_size; i++)
{
ch = *(intext + i);
*(outtext + i) = ALPHA_CH(ch) ? NUMCHAR( modn( CHARNUM(ch) -
*(shift + modp(i, shift_size)), 26) ) : ch;
}
}
cifer-1.2.0/src/utility.h 0000644 0001750 0001750 00000003521 11156502713 013407 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define INSERTION_DEFINE(ty, sval) void insertion_sort_ ## ty \
(ty *a, int asize);
#define GET_DEFINE(nm, ty, sval, svalty, comp) ty nm ## _ ## ty \
(ty *a, int asize);
#define GET_KEY_DEFINE(nm, ty, sval, svalty, comp) int nm ## _ ## ty ## _key \
(ty *a, int asize);
#include "utility.inc"
#undef GET_KEY_DEFINE
#undef GET_DEFINE
#undef INSERTION_DEFINE
#define IS_COPRIME(a, b) (gcd((a), (b)) == 1 ? 1 : 0)
int modular_multiplicative_inverse(int a, int b);
int gcd(int a, int b);
void *malloc_good(size_t size);
void *realloc_good(void *ptr, size_t size);
size_t strtlens(const char *s, size_t sz);
size_t strlefts(const char *s, size_t sz);
size_t strrights(const char *s, size_t sz);
size_t stralens(const char *s, size_t sz);
void cf_wordwrap(char *text, int text_size, int *nl_array);
#define strtlen(s) (strtlens(s, strlen(s)))
#define strleft(s) (strlefts(s, strlen(s)))
#define strright(s) (strrights(s, strlen(s)))
#define stralen(s) (stralens(s, strlen(s)))
cifer-1.2.0/src/bacon.h 0000644 0001750 0001750 00000001621 11156502713 012765 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
extern char *bacon_alphabet[26];
void bacon_encode(char *intext, int intext_size, char *outtext);
void bacon_decode(char *intext, int intext_size, char *outtext);
cifer-1.2.0/src/command.h 0000644 0001750 0001750 00000002563 11156502713 013327 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define CFSH_PARSE_OK 0
#define CFSH_PARSE_EBAD -2
#define CFSH_PARSE_EMPTY -5
#define CFSH_PARSE_QUOTEOPEN -9
#define CFSH_FUNC_OK 0
#define CFSH_FUNC_NOEXIST -1
typedef int(*cfsh_command)(int argc, char **argv);
typedef struct
{
cfsh_command command;
int argc;
char **argv;
} cfsh_execinfo;
int cfsh_parse(char *input, cfsh_execinfo *execinfo);
int cfsh_get_func(char *name, cfsh_command *command);
char *cfsh_get_usage(char *name);
char *cfsh_get_use(char *name);
void cfsh_free_execinfo(cfsh_execinfo *execinfo);
#define cfsh_exec(execinfo) execinfo.command(execinfo.argc, execinfo.argv);
cifer-1.2.0/src/stdinc.h 0000644 0001750 0001750 00000003113 11156502713 013165 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#ifndef STDINC_CIFER
#define STDINC_CIFER 1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "settings.h"
#include "macros.h"
#include "command_info.h"
#include "frequency_analysis.h"
#include "frequency_data.h"
#include "affine.h"
#include "bacon.h"
#include "ciphers.h"
#include "columnar_transposition.h"
#include "keyword.h"
#include "polybius.h"
#include "rf.h"
#include "vigenere.h"
#include "command.h"
#include "io.h"
#include "shell.h"
#include "actions.h"
#include "dictionary.h"
#include "interface.h"
#include "utility.h"
#endif
cifer-1.2.0/src/frequency_analysis.c 0000644 0001750 0001750 00000015337 11156502713 015613 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
/* TODO: Make the random frequency match function (bruteforce) try various
* combinations of suggestions in the sorted array (removing one option,
* then two, sliding about, etc.) and score the results, for better monoalph
* craxin
* Perhaps we could have some genetic algorithm ownage here? */
/* This function takes two graphs and tries to generate the best match
* table. (table being array[source] => identity or array[cipher] => plain */
void random_frequency_match(int *frequency_graph,
int *identity_frequency_graph,
int *table)
{
/* In order to take into account all the crossmatching and consider
* all the data in one go, we build up a struct array of diffs, scores
* sources and targets; then sort & extract. Tastey. */
/* stack variables */
int i, j, k;
rand_freq scores[26 * 26];
/* Load up the structs */
for (i = 0; i < 26; i++) for (j = 0; j < 26; j++)
{
k = (i * 26) + j;
scores[k].source = i;
scores[k].target = j;
scores[k].diff = diff(frequency_graph[i], identity_frequency_graph[j]);
}
/* Sort. */
insertion_sort_rand_freq(scores, 26 * 26);
/* Zero the table */
for (i = 0; i < 26; i++) table[i] = -1;
/* Extract the information. */
for (i = 0; i < (26 * 26); i++)
{
/* If the source is not taken... */
if (table[scores[i].source] == -1)
{
/* Check if the target is taken */
k = 1;
for (j = 0; j < 26; j++) if (table[j] == scores[i].target) k = 0;
/* And save */
if (k)
{
table[scores[i].source] = scores[i].target;
}
}
}
/* Done */
}
void frequency_guesses(char *intext, int intext_size,
char *outtext, int do_decrypt)
{
int frequency_graph[26], identity_frequency_graph[26], gid_freq[26];
int table[26], rtable[26], width[26];
int i, m, t, c;
char o;
/* Count */
count_freq(intext, intext_size, frequency_graph);
/* Because only alpha chars are counted, we need a new total */
t = 0;
for (i = 0; i < 26; i++) t += frequency_graph[i];
/* Now identity frequency graph time */
create_identity_frequency_graph(identity_frequency_graph, t);
/* Process */
random_frequency_match(frequency_graph, identity_frequency_graph, table);
/* Setup the guessed plainchar frequency information */
for (i = 0; i < 26; i++)
{
gid_freq[i] = identity_frequency_graph[table[i]];
}
/* Print out the information we gathered */
printf("Charnums and Frequencies: \n");
print_setup_width(width, &m);
print_count_width(frequency_graph, width, &m);
print_count_width(identity_frequency_graph, width, &m);
print_count_width(table, width, &m);
print_count_width(gid_freq, width, &m);
print_finalise_width(width, &m);
printf("C|");
for (i = 0; i < 26; i++) printf("%*c|", width[i], NUMCHAR(i));
printf("\n");
printf("N|");
for (i = 0; i < 26; i++) printf("%*i|", width[i], i);
printf("\n");
printf("F|");
for (i = 0; i < 26; i++) printf("%*i|", width[i], frequency_graph[i]);
printf("\n");
printf("I|");
for (i = 0; i < 26; i++)
printf("%*i|", width[i], identity_frequency_graph[i]);
printf("\n\n");
printf("Guessed Letters, ctext => ptext: \n");
printf("C|");
for (i = 0; i < 26; i++) printf("%*c|", width[i], NUMCHAR(i));
printf("\n");
printf("G|");
for (i = 0; i < 26; i++) printf("%*c|", width[i], NUMCHAR(table[i]));
printf("\n");
printf("Guessed letters, ptext => ctext: \n");
for (i = 0; i < 26; i++) rtable[table[i]] = i;
printf("G|");
for (i = 0; i < 26; i++) printf("%*c|", width[i], NUMCHAR(i));
printf("\n");
printf("C|");
for (i = 0; i < 26; i++) printf("%*c|", width[i], NUMCHAR(rtable[i]));
printf("\n\n");
if (do_decrypt)
{
printf("*Possible* but unlikely decrypt based purely on letters: \n");
for (i = 0; i < intext_size; i++)
{
o = *(intext + i);
c = CHARNUM(o);
if (c != -1) o = NUMCHAR(table[c]);
if (outtext != NULL) *(outtext + i) = o;
printf("%c", o);
}
printf("\n\n");
}
}
/* This frequency counter & analyser is different in that it incorporates
* jumps; ie, columns */
int frequency_analysis(char *text, int text_size, int jump)
{
int frequency_graph[26];
int identity_frequency_graph[26];
int i, j, h, ch, temp_diff, best_diff, best_diff_shift;
/* Prepare the variables */
best_diff = -1;
best_diff_shift = 0;
j = 0;
h = 0;
/* Zero the freq. graph and then scan the text */
for (i = 0; i < 26; i++) frequency_graph[i] = 0;
/* J is used to temporarily store the total text/column size */
/* H is used to count up to a jump */
i = 0;
while (i < text_size)
{
ch = CHARNUM(*(text + i));
i++;
if (ch != -1)
{
if (modp(h, jump) == 0)
{
frequency_graph[ch] += 1;
j++;
}
h++;
}
}
/* Setup the identity freq graphs */
create_identity_frequency_graph(identity_frequency_graph, j);
for (i = 0; i < 26; i++)
{
temp_diff = 0;
/* Compare the new letters against the identity */
for (j = 0; j < 26; j++)
{
temp_diff += diff(frequency_graph[modp(j + i, 26)],
identity_frequency_graph[j]);
}
/* And keep track of the best match */
if (best_diff == -1 || temp_diff < best_diff)
{
best_diff = temp_diff;
best_diff_shift = i;
}
}
return best_diff_shift;
}
double delta_ic (char *text, int text_size, int jump)
{
int sfreq[26];
int i, t;
double j;
j = 0; t = 0;
/* Zero the char freq array; then count up the char freqs, then
* calculate (3rd for) the top half of the fraction, 4 - total the chars
* counted, finally, do the dividing from the bottom half */
for (i = 0; i < 26; i++) sfreq[i] = 0;
for (i = 0; i < text_size; i += jump) sfreq[CHARNUM(*(text + i))] += 1;
for (i = 0; i < 26; i++) j += sfreq[i] * (sfreq[i] - 1);
for (i = 0; i < 26; i++) t += sfreq[i];
j = j / (t * (t - 1) / 26);
return j;
}
cifer-1.2.0/src/dictionary.c 0000644 0001750 0001750 00000031444 11156502713 014051 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
/* The dictionary must be sorted, normal ubuntu dict has all captials then all
* lowers, eg A-Z then a-z which Doesn't help =X
* cat /usr/share/dict/british-english | sort > dict */
#include "stdinc.h"
char *dict;
char **dict_pointer;
char **dict_pointer_end;
void score_text_pro_start(int text_size, score_text_pro_state *state)
{
if (text_size < 2)
{
printf("score_text_pro will not work with text_size < 2; failing.\n");
state->text_size = 0;
return;
}
/* Pre malloc_good all the space needed */
state->text_size = text_size;
state->frequency_graph_tolerance = text_size / 3;
state->frequency_graph = malloc_good( sizeof(int) * 26 );
state->identity_frequency_graph = malloc_good( sizeof(int) * 26 );
state->digrams_temp = malloc_good( sizeof(digram) * 26 * 26 );
state->trigrams_temp = malloc_good( sizeof(trigram) * 26 * 26 * 26 );
/* Setup id. frequency graph */
create_identity_frequency_graph(state->identity_frequency_graph, text_size);
/* Setup the counters */
state->num_checked = 0;
state->num_checked_freq_ok = 0;
state->num_checked_the_ok = 0;
/* So that any function knows its all good */
state->init_check = DICT_INIT_CHECK;
}
void score_text_pro_cleanup(score_text_pro_state *state)
{
free(state->digrams_temp);
free(state->trigrams_temp);
free(state->frequency_graph);
free(state->identity_frequency_graph);
}
void score_text_pro_print_stats(char *englishname, score_text_pro_state *state)
{
printf("Score text pro '%s' stats:\n", englishname);
printf(" Number of Texts checked: %i\n",
state->num_checked);
printf(" Number of Texts checked with ok frequency_graph: %i (tol. %i)\n",
state->num_checked_freq_ok, state->frequency_graph_tolerance);
printf(" Number of Texts checked with ok 'THE' location: %i\n\n",
state->num_checked_the_ok);
}
int score_text_pro(char *text, score_text_pro_state *state)
{
int i, j, k, h, l, fg_diff, temp_th_num;
digram temp_th;
trigram temp_the;
/* This routine is made to quickly discard garbage but generate a better
* score for real matches */
if (state->init_check != DICT_INIT_CHECK) return 0;
state->num_checked ++;
/* Reset the variables */
fg_diff = 0;
for (i = 0; i < 26; i++) state->frequency_graph[i] = 0;
/* This will have been sorted, so it all must be reset */
h = 0;
for (i = 0; i < 26; i++) for (j = 0; j < 26; j++)
{
state->digrams_temp[h].digram_ch1 = i;
state->digrams_temp[h].digram_ch2 = j;
state->digrams_temp[h].digram_value = 0;
h++;
}
/* Same */
h = 0;
for (i = 0; i < 26; i++) for (j = 0; j < 26; j++) for (k = 0; k < 26; k++)
{
state->trigrams_temp[h].trigram_ch1 = i;
state->trigrams_temp[h].trigram_ch2 = j;
state->trigrams_temp[h].trigram_ch3 = k;
state->trigrams_temp[h].trigram_value = 0;
h++;
}
/* This loop will search through, matching all single letters above
* [0] and [1] (because trigams say so) and all digrams except [1];
* which must be counted afterwards */
/* Combine the Frequency analysis, digram + trigram loops into one */
l = state->text_size - 2; /* For Trigrams */
for (i = 0; i < l; i++)
{
j = CHARNUM(*(text + i + 2));
h = CHARNUM(*(text + i + 1));
k = CHARNUM(*(text + i));
if (j != -1 && h != -1 && k != -1)
{
h = (h * 26) + j;
k = (k * 676) + h;
state->trigrams_temp[k].trigram_value ++;
state->digrams_temp[h].digram_value ++;
state->frequency_graph[j] ++;
}
}
i = CHARNUM(*text);
j = CHARNUM(*(text + 1));
if (i != -1 && j != -1)
{
h = (i * 26) + j;
state->digrams_temp[h].digram_value ++;
state->frequency_graph[i] ++;
state->frequency_graph[j] ++;
}
/* Generate some sort of "diff" for the frequency graph */
for (i = 0; i < 26; i++)
{
fg_diff += diff(state->frequency_graph[i],
state->identity_frequency_graph[i]);
}
/* Does it meet the cutoff ? */
if (fg_diff > state->frequency_graph_tolerance)
{
/* Missed the cutoff; return a score < 100 */
return max(100 - (fg_diff - state->frequency_graph_tolerance), 1);
}
state->num_checked_freq_ok ++;
/* Carry on procesing! Lets check for THE. (copied from affine.c) */
temp_the = best_trigram(state->trigrams_temp, 17576);
j = 0; /* All is ok (this should reach 3) */
/* Check that we have found THE. */
if (temp_the.trigram_ch1 == 19 || temp_the.trigram_ch2 == 7 ||
temp_the.trigram_ch3 == 4)
{
j += 1;
}
/* Check that we can find a TH digram */
for (i = 0; i < 10; i++)
{
/* Get a good digram (the best, actually) */
temp_th_num = best_digram_key(state->digrams_temp, 676);
temp_th = state->digrams_temp[temp_th_num];
if (temp_th.digram_ch1 == 19 &&
temp_th.digram_ch2 == 7)
{
j += 2;
break;
}
/* Fail? Remove that digram by setting it to 0, then get the next best */
state->digrams_temp[temp_th_num].digram_value = 0;
}
if (j != 3)
{
/* Can't find it. Return a score less than 200, based on freq. */
return max(200 - fg_diff, 1);
}
state->num_checked_the_ok ++;
/* OK! All is looking good so far. Ish. Now we're clear to run a full
* dictionary check on this; returning 200 + score */
return 200 + score_text_dict_fast(text, state->text_size);
}
int score_text_dict_fast(char *text, int size)
{
int i, jlen_buf, prefix, match_size, score;
char *test_start, *test_end, *j;
char ch1, ch2;
/* Check */
if (dict == NULL) return 0;
/* Prepare */
match_size = 1;
score = 0;
/* If it gets to size - MIN_WORD_SIZE we won't find the last bit anyway
* because it's limited by MIN_WORD_SIZE */
for (i = 0; i < (size - MIN_WORD_SIZE); i += max(match_size, 1))
{
ch1 = *(text + i);
ch2 = *(text + i + 1);
match_size = 0;
if (ALPHA_CH(ch1) && ALPHA_CH(ch2))
{
prefix = (CHARNUM( ch1 ) * 26) + CHARNUM( ch2 );
test_start = *(dict_pointer + prefix);
test_end = *(dict_pointer_end + prefix);
for (j = test_start; j < test_end; j += jlen_buf + 1) /* Remember \0 */
{
/* In theory, the \0 terminators should take care of all size checks,
* we use strncmp to limit to checking the correct size of text. */
jlen_buf = strlen(j);
if (jlen_buf > match_size && strncasecmp(j, text + i, jlen_buf) == 0)
match_size = jlen_buf;
}
score += match_size;
}
}
return score;
}
void score_text_dict_spaces(char *text, int size, int *space_array)
{
int i, jlen_buf, prefix, match_size, super_size, failing;
char *test_start, *test_end, *j;
char ch1, ch2;
if (dict == NULL) return;
match_size = 1;
failing = 0;
for (i = 0; i < size; i++) *(space_array + i) = 0;
for (i = 0; i < (size - MIN_WORD_SIZE); i += max(match_size, 1))
{
ch1 = *(text + i);
ch2 = *(text + i + 1);
match_size = 0;
super_size = 0;
/* For spacing, we don't care about speed or score, so we use
* this hard coded preference list to make it readable */
#define superword(w) if (strncasecmp(w, text + i, sizeof(w) - 1) == 0) \
super_size = sizeof(w) - 1;
if (ALPHA_CH(ch1) && ALPHA_CH(ch2))
{
superword("the")
else superword("of")
else superword("to")
else superword("in")
else superword("and")
else superword("for")
else superword("was")
else superword("is")
else superword("that")
else superword("on")
else superword("at")
else superword("he")
else superword("with")
else superword("by")
else superword("be")
else superword("it")
else superword("an")
else superword("his")
match_size = super_size;
prefix = (CHARNUM( ch1 ) * 26) + CHARNUM( ch2 );
test_start = *(dict_pointer + prefix);
test_end = *(dict_pointer_end + prefix);
for (j = test_start; j < test_end; j += jlen_buf + 1)
{
jlen_buf = strlen(j);
if (jlen_buf > match_size && strncasecmp(j, text + i, jlen_buf) == 0)
match_size = jlen_buf;
}
/* Something like this its worth hinting in super's favour */
if (match_size - 1 == super_size) match_size = super_size;
if (match_size != 0)
{
if (failing) *(space_array + i - 1) = 1;
*(space_array + i + match_size - 1) = 1;
failing = 0;
}
else
{
failing = 1;
}
}
}
}
void init_dict(void)
{
/* Simply initialises the pointers */
dict = NULL;
dict_pointer = NULL;
dict_pointer_end = NULL;
}
void unload_dict(int notice)
{
if (notice != 1) printf(dict_not_loaded);
if (dict != NULL) free(dict);
if (dict_pointer != NULL) free(dict_pointer);
if (dict_pointer_end != NULL) free(dict_pointer_end);
dict = NULL;
dict_pointer = NULL;
dict_pointer_end = NULL;
}
void load_dict(char *location)
{
FILE *dictf;
int i, j, filesize;
int last_prefix, prefix;
char ch;
char *dict_insert, *dict_end;
char buf[WORD_BUF_SIZE];
int buf_size;
int searching;
/* Check */
if (location == NULL || strtlen(location) == 0)
{
printf("load_dict: please specify a dict location\n");
unload_dict(0);
return;
}
if (dict != NULL) unload_dict(1);
dictf = fopen(location, "r");
if (dictf == NULL)
{
perror("load_dict: fopen");
unload_dict(0);
return;
}
/* Count filesize */
filesize = 0;
buf_size = 0;
while (feof(dictf) == 0)
{
ch = getc(dictf);
if (ALPHA_CH(ch))
{
buf_size++;
if (buf_size >= WORD_BUF_SIZE)
{
printf("Error: A Word busted WORD_BUF_SIZE %i\n", WORD_BUF_SIZE);
unload_dict(0);
return;
}
}
else if (IS_NEWLINE(ch))
{
if (buf_size > MIN_WORD_SIZE)
{
filesize += buf_size + 1;
}
buf_size = 0;
}
}
rewind(dictf);
dict = malloc_good( filesize + 1 );
dict_pointer = malloc_good( sizeof(char *) * ((26 * 26) + 1) );
dict_pointer_end = malloc_good( sizeof(char *) * ((26 * 26) + 1) );
dict_insert = dict;
buf_size = 0;
printf("Loading dictionary of %i bytes... ", filesize);
fflush(stdout);
/* Read it in */
i = 0;
while (feof(dictf) == 0)
{
ch = getc(dictf);
if (ALPHA_CH(ch))
{
buf[buf_size] = ch;
buf_size++;
}
else if (IS_NEWLINE(ch))
{
if (buf_size > MIN_WORD_SIZE)
{
if ((i + buf_size) >= filesize)
{
printf("\n");
printf("*dict overflow at %i (Attempted to add %i)\n", i, buf_size);
unload_dict(0);
return;
}
memcpy(dict_insert, buf, buf_size);
*(dict_insert + buf_size) = 0;
dict_insert += buf_size + 1;
i += buf_size + 1;
}
buf_size = 0;
}
}
/* Close the file */
fclose(dictf);
printf("Done.\n");
printf("Indexing the dictionary... ");
fflush(stdout);
/* Build up our quickjump pointaz */
searching = 1;
dict_insert = dict;
last_prefix = -1;
for (i = 0; i < (26 * 26); i++)
{
*(dict_pointer + i) = NULL;
*(dict_pointer_end + i) = NULL;
}
/* Set the final one to be the very end; the final \0 to show filesize */
dict_end = (dict + filesize);
*(dict_pointer + (26 * 26)) = dict_end;
while (searching)
{
j = strlen(dict_insert);
if (j <= MIN_WORD_SIZE)
{
printf("Word length is %i (< %i), dict load fail.\n", j, MIN_WORD_SIZE);
unload_dict(0);
return;
}
else
{
prefix = (CHARNUM( (char) *dict_insert ) * 26) +
CHARNUM( (char) *(dict_insert + 1) );
}
if (prefix != last_prefix)
{
/* Start the next prefix */
*(dict_pointer + prefix) = dict_insert;
/* Mark the end */
if (last_prefix != -1)
{
dict_pointer_end[last_prefix] = dict_insert;
}
last_prefix = prefix;
}
dict_insert += j + 1;
if (dict_insert >= dict_end)
{
searching = 0;
}
}
printf("Done.\n");
fflush(stdout);
}
cifer-1.2.0/src/frequency_analysis.h 0000644 0001750 0001750 00000002254 11156502713 015612 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
typedef struct {
int source;
int target;
int diff;
} rand_freq;
void random_frequency_match(int *frequency_graph,
int *identity_frequency_graph,
int *table);
void frequency_guesses(char *intext, int intext_size,
char *outtext, int do_decrypt);
int frequency_analysis(char *text, int text_size, int jump);
double delta_ic (char *text, int text_size, int jump);
cifer-1.2.0/src/command.inc 0000644 0001750 0001750 00000017651 11156502713 013655 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
cfsh_func("buffers" , action_buffers)
cfsh_func("quit" , action_quit)
cfsh_func("exit" , action_quit)
cfsh_func("resize" , action_resize)
cfsh_func("clear" , action_clear)
cfsh_func("copy" , action_copy)
cfsh_func("load" , action_load)
cfsh_func("write" , action_write)
cfsh_func("filter" , action_filter)
cfsh_func("read" , action_read)
cfsh_func("print" , action_read)
cfsh_func("bufferinfo" , action_bufferinfo)
cfsh_func("getsize" , action_bufferinfo)
cfsh_func("getfilter" , action_bufferinfo)
cfsh_func("nullbuffer" , action_nullbuffer)
cfsh_func("file" , action_script)
cfsh_func("script" , action_script)
cfsh_func("quickfile" , action_quickscript)
cfsh_func("quickscript" , action_quickscript)
cfsh_func("softfile" , action_softscript)
cfsh_func("softscript" , action_softscript)
cfsh_func("quicksoftfile" , action_quicksoftscript)
cfsh_func("quicksoftscript" , action_quicksoftscript)
cfsh_func("score" , action_score)
cfsh_func("spaces" , action_spaces)
cfsh_func("wordwrap" , action_wordwrap)
cfsh_func("ww" , action_wordwrap)
cfsh_func("wrap" , action_wordwrap)
cfsh_func("loaddict" , action_loaddict)
cfsh_func("load_dict" , action_loaddict)
cfsh_func("affine" , action_affine)
cfsh_func("crack_affine" , action_affine)
cfsh_func("affinesolve" , action_affinesolve)
cfsh_func("affine_solve" , action_affinesolve)
cfsh_func("affinebf" , action_affinebf)
cfsh_func("affine_bf" , action_affinebf)
cfsh_func("affine_encode" , action_affineencode)
cfsh_func("affineencode" , action_affineencode)
cfsh_func("affinee" , action_affineencode)
cfsh_func("affine_decode" , action_affinedecode)
cfsh_func("affinedecode" , action_affinedecode)
cfsh_func("affined" , action_affinedecode)
cfsh_func("baconencode" , action_baconencode)
cfsh_func("bacon_encode" , action_baconencode)
cfsh_func("baconenc" , action_baconencode)
cfsh_func("bacondecode" , action_bacondecode)
cfsh_func("bacon" , action_bacondecode)
cfsh_func("bacon_decode" , action_bacondecode)
cfsh_func("bacondec" , action_bacondecode)
cfsh_func("crack_bacon" , action_bacondecode)
cfsh_func("shift" , action_shift)
cfsh_func("vigenere_manual" , action_shift)
cfsh_func("deltaic" , action_deltaic)
cfsh_func("delta_ic" , action_deltaic)
cfsh_func("monoalph" , action_monoalph)
cfsh_func("ctrans_keyinfo" , action_ctrans_keyinfo)
cfsh_func("keyinfo" , action_ctrans_keyinfo)
cfsh_func("c2c_encode" , action_c2c_encode)
cfsh_func("c2c_decode" , action_c2c_decode)
cfsh_func("c2c_bruteforce" , action_c2c_bruteforce)
cfsh_func("r2c_encode" , action_r2c_encode)
cfsh_func("r2c_decode" , action_r2c_decode)
cfsh_func("r2c_bruteforce" , action_r2c_bruteforce)
cfsh_func("c2r_encode" , action_c2r_encode)
cfsh_func("c2r_decode" , action_c2r_decode)
cfsh_func("c2r_bruteforce" , action_c2r_bruteforce)
cfsh_func("fg" , action_fg)
cfsh_func("frequency_guesses" , action_fg)
cfsh_func("ifg" , action_ifg)
cfsh_func("identity_frequency_graph" , action_ifg)
cfsh_func("fa" , action_fa)
cfsh_func("count_freq" , action_fa)
cfsh_func("frequency" , action_fa)
cfsh_func("frequency_analysis" , action_fa)
cfsh_func("digrams" , action_digrams)
cfsh_func("count_digrams" , action_digrams)
cfsh_func("trigrams" , action_trigrams)
cfsh_func("count_trigrams" , action_trigrams)
cfsh_func("pct" , action_pct)
cfsh_func("chartable" , action_pct)
cfsh_func("keyb" , action_keyb)
cfsh_func("keyword_bruteforce" , action_keyb)
cfsh_func("keye" , action_keye)
cfsh_func("keyword_encode" , action_keye)
cfsh_func("keyd" , action_keyd)
cfsh_func("keyword_decode" , action_keyd)
cfsh_func("keyt" , action_keyt)
cfsh_func("keyword_table" , action_keyt)
cfsh_func("keytf" , action_keytf)
cfsh_func("keyword_table_flipped" , action_keytf)
cfsh_func("polybius_encode" , action_polybius_encode)
cfsh_func("polybiusencode" , action_polybius_encode)
cfsh_func("polybius_decode" , action_polybius_decode)
cfsh_func("polybiusdecode" , action_polybius_decode)
cfsh_func("polybius" , action_polybius_decode)
cfsh_func("rfbf" , action_rfbf)
cfsh_func("railfence" , action_rfbf)
cfsh_func("rf" , action_rfbf)
cfsh_func("vigenere" , action_vigenere)
cfsh_func("vigenere_crack" , action_vigenere)
cfsh_func("mmi" , action_mmi)
cfsh_func("modmulinv" , action_mmi)
cfsh_func("gcd" , action_gcd)
cfsh_func("greatest_common_denominator" , action_gcd)
cfsh_func("coprime" , action_coprime)
cfsh_func("is_coprime" , action_coprime)
cfsh_func("charinfo" , action_charinfo)
cfsh_func("char_info" , action_charinfo)
cfsh_func("char" , action_charinfo)
cfsh_func("usage" , action_usage)
cfsh_func("info" , action_usage)
cfsh_func("help" , action_help)
cfsh_func("system" , action_system)
cfsh_func("exec" , action_system)
cfsh_func("-" , action_system)
cfsh_func(";" , action_system)
cfsh_func("s" , action_system)
cfsh_func("cd" , action_cd)
cfsh_func("cwd" , action_cd)
cfsh_func("ls" , action_ls)
cfsh_func("list" , action_ls)
cfsh_func("dir" , action_ls)
cifer-1.2.0/src/frequency_data.h 0000644 0001750 0001750 00000002462 11156502713 014701 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
extern double english_frequency[26];
typedef struct {
int digram_ch1;
int digram_ch2;
int digram_value;
} digram;
typedef struct {
int trigram_ch1;
int trigram_ch2;
int trigram_ch3;
int trigram_value;
} trigram;
void create_identity_frequency_graph(int *frequency_graph, int text_size);
/* Returns an int array[26] with letter frequencies of input text */
void count_freq(char *text, int input_size, int *tgt);
void count_digrams(char *text, int input_size, digram *tgt, int tgt_size);
void count_trigrams(char *text, int input_size, trigram *tgt, int tgt_size);
cifer-1.2.0/src/utility.c 0000644 0001750 0001750 00000011777 11156502713 013416 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
void *malloc_good(size_t size)
{
void *r;
r = malloc(size);
if (r == NULL)
{
printf("\n\nmalloc_good: Unable to malloc(%lu), auto-exiting\n\n",
(unsigned long) size);
exit(1);
}
return r;
}
void *realloc_good(void *ptr, size_t size)
{
void *r;
r = realloc(ptr, size);
if (size != 0 && r == NULL)
{
printf("\n\nrealloc_good: Unable to realloc(%lu), auto-exiting\n\n",
(unsigned long) size);
exit(1);
}
return r;
}
size_t strtlens(const char *s, size_t sz)
{
return sz - strlefts(s, sz) - strrights(s, sz);
}
size_t stralens(const char *s, size_t sz)
{
int i, c;
for (i = 0, c = 0; i < sz; i++)
if (ALPHA_CH(*(s + i))) c++;
return c;
}
size_t strlefts(const char *s, size_t sz)
{
int i, left;
char ch;
for (i = 0, left = 0; i < sz; i++)
{
ch = *(s + i);
if (XSPACE_CH(ch) || SPACE_CH(ch)) left++;
else break;
}
return left;
}
size_t strrights(const char *s, size_t sz)
{
int i, right;
char ch;
for (i = sz - 1, right = 0; i >= 0; i--)
{
ch = *(s + i);
if (XSPACE_CH(ch) || SPACE_CH(ch)) right++;
else break;
}
return right;
}
void cf_wordwrap(char *text, int text_size, int *nl_array)
{
int i, lastspace, linelen;
char ch;
lastspace = -1;
for (i = 0; i < text_size; i++) *(nl_array + i) = 0;
for (i = 0, linelen = 0; i < text_size; i++, linelen++)
{
ch = *(text + i);
if (SPACE_CH(ch)) lastspace = i;
if (linelen >= 70)
{
if (lastspace == -1)
{
*(nl_array + i) = 1;
linelen = 0;
}
else
{
*(nl_array + lastspace) = 1;
linelen = i - lastspace - 1;
}
lastspace = -1;
}
}
}
/* The following macro is a condensed version of this code
* void insertion_columnic_sort(vigenere_column_ic a[], int asize)
* {
* int i, j, k;
* vigenere_column_ic d;
*
* k = asize - 1;
* for (i = 0; i < k; i++)
* {
* d = a[i];
* j = i - 1;
*
* while (j >= 0 && a[j].column_ic_diff > d.column_ic_diff)
* {
* a[j + 1] = a[j];
* j = j - 1;
* }
*
* a[j + 1] = d;
* }
* } */
#define INSERTION_DEFINE(ty, sval) void insertion_sort_ ## ty \
(ty *a, int asize) { \
int i, j, k; ty d; k = asize; for (i = 0; i < k; i++) { \
d = a[i]; j = i - 1; while (j >= 0 && a[j].sval > d.sval) { \
a[j + 1] = a[j]; j = j - 1; } a[j + 1] = d; } }
#define GET_DEFINE(nm, ty, sval, svalty, comp) ty nm ## _ ## ty \
(ty *a, int asize) { \
int i, best_key; svalty best; best = a[0].sval; best_key = 0; \
for (i = 1; i < asize; i++) \
if (a[i].sval comp best) { best = a[i].sval; best_key = i; } \
return a[best_key]; }
#define GET_KEY_DEFINE(nm, ty, sval, svalty, comp) int nm ## _ ## ty ## _key \
(ty *a, int asize) { \
int i, best_key; svalty best; best = a[0].sval; best_key = 0; \
for (i = 1; i < asize; i++) \
if (a[i].sval comp best) { best = a[i].sval; best_key = i; } \
return best_key; }
#include "utility.inc"
#undef GET_KEY_DEFINE
#undef GET_DEFINE
#undef INSERTION_DEFINE
/* And this one is the same for this function:
* vigenere_colum_ic max_columnic(vigenere_column_ic a[], int asize)
* {
* int i, best, best_key;
*
* best = a[0];
* for (i = 1; i < asize; i++) if (a[i].column_ic_diff > best)
* { best = a[i].column_ic_diff; best_key = i; }
*
* return a[best_key];
* }
* And min_ is just the opposite comparison */
/* a = number; b = modular */
int modular_multiplicative_inverse(int a, int mbase)
{
int b, x, y, temp, quotient, lastx, lasty;
b = mbase;
x = 0; y = 1;
lastx = 1; lasty = 0;
while (b != 0)
{
temp = b;
quotient = a / b;
b = modn(a, b);
a = temp;
temp = x;
x = lastx - (quotient * x);
lastx = temp;
temp = y;
y = lasty - (quotient * y);
lasty = temp;
}
return modn(lastx, mbase);
}
int gcd(int a, int b)
{
if (b == 0) return a;
else return gcd(b, modn(a, b));
}
cifer-1.2.0/src/keyword.h 0000644 0001750 0001750 00000002653 11156502713 013375 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
void keyword_bruteforce(char *intext, int intext_size, char *outtext);
void keyword_table(char *keyword, int keyword_length, int *table);
void keyword_table_preflipped(char *keyword, int keyword_length, int *table);
void keyword_table_flip(int *table);
void keyword_translate(char *intext, int text_size, char *outtext, int *table);
void keyword_table_copy(int *dest, int *source);
void keyword_single(char *intext, int intext_size, char *outtext,
char *keyword, int key_size, int flip);
void keyword_print_keyinfo(int *table);
void keyword_print_info(char *text, char *keyword,
int *table, char *dirstring);
int keyword_check(char *keyword, int key_size);
cifer-1.2.0/src/dictionary.h 0000644 0001750 0001750 00000003167 11156502713 014057 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define DICT_INIT_CHECK 297 /* Just some random number ;) */
extern char *dict;
extern char **dict_pointer;
extern char **dict_pointer_end;
typedef struct {
int text_size;
int frequency_graph_tolerance;
int num_checked;
int num_checked_freq_ok;
int num_checked_the_ok;
int *frequency_graph;
int *identity_frequency_graph;
digram *digrams_temp;
trigram *trigrams_temp;
int init_check;
} score_text_pro_state;
void init_dict(void);
void unload_dict(int notice);
void load_dict(char *location);
int score_text_dict_fast(char *text, int size);
void score_text_dict_spaces(char *text, int size, int *space_array);
void score_text_pro_start(int text_size, score_text_pro_state *state);
void score_text_pro_cleanup(score_text_pro_state *state);
void score_text_pro_print_stats(char *englishname, score_text_pro_state *state);
int score_text_pro(char *text, score_text_pro_state *state);
cifer-1.2.0/src/actions_analysis.c 0000644 0001750 0001750 00000014005 11156502713 015241 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
#define ACTION_USAGE action_deltaic_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_deltaic(int argc, char **argv)
{
int buffer_id;
double result;
actionu_argchk(1)
actionu_bufferparse(*(argv), buffer_id)
result = delta_ic(get_buffer(buffer_id), get_buffer_real_size(buffer_id), 1);
printf("The DELTA_IC of buffer_%i is %f\n", buffer_id, result);
printf("A typical value for English is %f. buffer_%i differs by %f.\n",
OPTIMAL_DELTA_IC, buffer_id, diff(result, OPTIMAL_DELTA_IC));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_fg_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_fg(int argc, char **argv)
{
int buffer_in, buffer_out;
char *outtext;
if (argc != 1 && argc != 2) actionu_fail()
actionu_bufferparse(*(argv), buffer_in)
outtext = NULL;
if (argc == 2)
{
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_bufferout_fn()
outtext = get_buffer(buffer_out);
}
else
{
printf("Add an extra buffer argument to save the possible-decrypt");
}
frequency_guesses(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
outtext, 1);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_ifg_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_ifg(int argc, char **argv)
{
int buffer_id, text_size, i, m;
int ifg[26], width[26];
actionu_argchk(1)
if (**argv == 'b')
{
actionu_bufferparse(*argv, buffer_id)
text_size = get_buffer_real_size(buffer_id);
}
else
{
actionu_intparse(*argv, text_size)
}
if (text_size < 0) text_size = 0;
create_identity_frequency_graph(ifg, text_size);
printf("Printing identity frequency graph for text_size %i\n", text_size);
print_setup_width(width, &m);
print_count_width(ifg, width, &m);
print_finalise_width(width, &m);
printf("C|");
for (i = 0; i < 26; i++) printf("%*c|", width[i], NUMCHAR(i));
printf("\n");
printf("N|");
for (i = 0; i < 26; i++) printf("%*i|", width[i], i);
printf("\n");
printf("F|");
for (i = 0; i < 26; i++) printf("%*i|", width[i], ifg[i]);
printf("\n\n");
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_fa_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_fa(int argc, char **argv)
{
int buffer_id;
actionu_argchk(1)
actionu_bufferparse(*(argv), buffer_id)
frequency_guesses(get_buffer(buffer_id), get_buffer_real_size(buffer_id),
NULL, 0);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_digrams_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_digrams(int argc, char **argv)
{
int buffer_id, num_to_show, i;
digram *tgt;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_id)
actionu_intparse(*(argv + 1), num_to_show)
if (get_buffer_real_size(buffer_id) < 2)
{
printf("Input buffer text too small\n");
actionu_faili()
}
if (num_to_show < 1) num_to_show = 1;
if (num_to_show > (26 * 26)) num_to_show = (26 * 26);
tgt = malloc_good( sizeof(digram) * num_to_show );
count_digrams(get_buffer(buffer_id), get_buffer_real_size(buffer_id),
tgt, num_to_show);
printf("Showing top %i digram%c..%c\n", num_to_show,
(num_to_show == 1 ? '.' : 's'),
(num_to_show == 1 ? ' ' : '.'));
for (i = 0; i < num_to_show; i++)
{
printf("Rank %i) \t %c%c\n", i, NUMCHAR(tgt[i].digram_ch1),
NUMCHAR(tgt[i].digram_ch2) );
}
printf("\n");
free(tgt);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_trigrams_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_trigrams(int argc, char **argv)
{
int buffer_id, num_to_show, i;
trigram *tgt;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_id)
actionu_intparse(*(argv + 1), num_to_show)
if (get_buffer_real_size(buffer_id) < 3)
{
printf("Input buffer text too small\n");
printf(action_trigrams_usage);
return CFSH_COMMAND_HARDFAIL;
}
if (num_to_show < 1) num_to_show = 1;
if (num_to_show > (26 * 26)) num_to_show = (26 * 26);
tgt = malloc_good( sizeof(trigram) * num_to_show );
count_trigrams(get_buffer(buffer_id), get_buffer_real_size(buffer_id),
tgt, num_to_show);
printf("Showing top %i trigram%c..%c\n", num_to_show,
(num_to_show == 1 ? '.' : 's'),
(num_to_show == 1 ? ' ' : '.'));
for (i = 0; i < num_to_show; i++)
{
printf("Rank %i) \t %c%c%c\n", i, NUMCHAR(tgt[i].trigram_ch1),
NUMCHAR(tgt[i].trigram_ch2),
NUMCHAR(tgt[i].trigram_ch3) );
}
printf("\n");
free(tgt);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_pct_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_pct(int argc, char **argv)
{
int i;
printf("C|");
for (i = 0; i < 26; i++) printf("%2c|", NUMCHAR(i));
printf("\n");
printf("N|");
for (i = 0; i < 26; i++) printf("%2i|", i);
printf("\n\n");
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
cifer-1.2.0/src/command_info.h 0000644 0001750 0001750 00000031257 11156502713 014344 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define dict_not_loaded "dictionary not loaded: type `usage load_dict' for more info\n"
#define actionu_bufferparse_fail "bad buffer name '%s', use 'buffer_#' (X, int 0 to %i)\n"
#define actionu_bufferparse_zerofail "bad buffer name '%s', please create some buffers with 'buffers'\n"
#define action_default_usage "usage: help (to list all commands) or usage \n";
#define action_default_use "no such command\n";
#define action_buffers_usage "usage: buffers # (num of buffers, > 0)\n"
#define action_quit_usage "usage: quit \n"
#define action_resize_usage "usage: buffer_# X (tgt buffer, new_size)\n"
#define action_clear_usage "usage: clear buffer_#\n"
#define action_copy_usage "usage: copy buffer_# buffer_# (src, tgt)\n"
#define action_load_usage "usage: load filename buffer_# (src, tgt)\n"
#define action_write_usage "usage: write filename buffer_# append|overwrite|auto (tgt, src)\n"
#define action_filter_usage "usage: buffer_# mode where mode is one of: \n\
alpha - Only alpha chars allowed. \n\
alphanum - Only alphanumeric chars \n\
lalpha - Only alpha chars, all converted to lower case. \n\
ualpha - Only alpha chars, conv. 2 uppercase. \n\
flipcase - Only alpha chars, upper/lower case flipped. \n\
casebacon - Only alpha, upper->'A' lower->'B'. \n\
bacon - Only As or Bs \n\
num - Only numbers \n\
esp - Removes all whitespace \n\
enl - Removes all whitespace except spaces. \n"
#define action_read_usage "usage: read buffer_#\n"
#define action_bufferinfo_usage "usage: bufferinfo buffer_#\n"
#define action_nullbuffer_usage "usage: nullbuffer buffer_#\n"
#define action_script_usage "usage: [quick][soft]script filename\n"
#define action_quickscript_usage "usage: [quick][soft]script filename\n"
#define action_softscript_usage "usage: [quick][soft]script filename\n"
#define action_quicksoftscript_usage "usage: [quick][soft]script filename\n"
#define action_score_usage "usage: score buffer_#\n"
#define action_spaces_usage "usage: spaces buffer_# buffer_# (input, output)\n"
#define action_wordwrap_usage "usage: wordwrap buffer_# buffer_# (input, output)\n"
#define action_loaddict_usage "usage: loaddict filename\n\
a dictionary can be created using the cifer-dict command \n\
(external to this shell), see the cifer-dict manpage for more info.\n\
Some functions will be unavailable without a dictionary. \n"
#define action_affine_usage "usage: affine buffer_# buffer_# (input, output)\n"
#define action_affinesolve_usage "usage: affinesolve ct1 pt1 ct2 pt2\n"
#define action_affinebf_usage "usage: affinebf buffer_# buffer_# (input, output)\n"
#define action_affineencode_usage "usage: affineencode buffer_# buffer_# # # (input, output, a, b)\n"
#define action_affinedecode_usage "usage: affinedecode buffer_# buffer_# # # (input, output, a, b)\n"
#define action_baconencode_usage "usage: baconencode buffer_# buffer_# (input, output)\n"
#define action_bacondecode_usage "usage: bacondecode buffer_# buffer_# (input, output)\n"
#define action_shift_usage "usage: shift buffer_# buffer_# forwards|backwards shift \n\
(input, output, encode|decode - direction, shift(s) in alpha or num)\n"
#define action_deltaic_usage "usage: deltai buffer_#\n"
#define action_monoalph_usage "usage: monoalph buffer_# buffer_# encrypt|decrypt ctext_targets \n\
(input, output, cipher mode, ctext_targets for abcd....xyz (alpha size 26))\n"
#define action_ctrans_keyinfo_usage "usage: keyword (in alpha (eg. tomato) or numbers (1 3 2 0) \n"
#define action_c2c_encode_usage "usage: c2c_encode buffer_# buffer_# keyword\n\
(input, output, keyword in alpha (eg. tomato) or numbers (1 3 2 0) \n"
#define action_r2c_encode_usage "usage: r2c_encode buffer_# buffer_# keyword\n\
(input, output, keyword in alpha (eg. tomato) or numbers (1 3 2 0) \n"
#define action_c2r_encode_usage "usage: c2r_encode buffer_# buffer_# keyword\n\
(input, output, keyword in alpha (eg. tomato) or numbers (1 3 2 0) \n"
#define action_c2c_decode_usage "usage: c2c_decode buffer_# buffer_# keyword\n\
(input, output, keyword in alpha (eg. tomato) or numbers (1 3 2 0) \n"
#define action_r2c_decode_usage "usage: r2c_decode buffer_# buffer_# keyword\n\
(input, output, keyword in alpha (eg. tomato) or numbers (1 3 2 0) \n"
#define action_c2r_decode_usage "usage: c2r_decode buffer_# buffer_# keyword\n\
(input, output, keyword in alpha (eg. tomato) or numbers (1 3 2 0) \n"
#define action_c2c_bruteforce_usage "usage: c2c_bruteforce buffer_# buffer_# # # \n\
(input, output, min, max) \n"
#define action_r2c_bruteforce_usage "usage: r2c_bruteforce buffer_# buffer_# # # \n\
(input, output, min, max) \n"
#define action_c2r_bruteforce_usage "usage: c2r_bruteforce buffer_# buffer_# # # \n\
(input, output, min, max) \n"
#define action_fg_usage "usage: fg buffer_# [buffer_#]\n"
#define action_ifg_usage "usage: ifg text_size|buffer_#\n"
#define action_fa_usage "usage: fa buffer_#\n"
#define action_digrams_usage "usage: digrams buffer_# num_to_show\n"
#define action_trigrams_usage "usage: trigrams buffer_# num_to_show\n"
#define action_pct_usage "usage: pct \n"
#define action_keyb_usage "usage: keyb buffer_# buffer_# (input, output)\n"
#define action_keye_usage "usage: keye buffer_# buffer_# keyword_text (input, output)\n"
#define action_keyd_usage "usage: keyd buffer_# buffer_# keyword_text (input, output)\n"
#define action_keyt_usage "usage: keyt keyword_text\n"
#define action_keytf_usage "usage: keytf keyword_text\n"
#define action_polybius_encode_usage "usage: polybius_encode buffer_# buffer_#\n"
#define action_polybius_decode_usage "usage: polybius_decode buffer_# buffer_#\n"
#define action_rfbf_usage "usage: rfbf buffer_# buffer_# min max (input, output, bf_range)\n"
#define action_vigenere_usage "usage: vigenere buffer_# buffer_# min max (input, output, bf_range)\n"
#define action_mmi_usage "usage: mmi int_value int_mod\n"
#define action_gcd_usage "usage: gcd int_arg1 int_arg2 ...\n"
#define action_coprime_usage "usage: coprime int_arg1 int_arg2\n"
#define action_charinfo_usage "usage: charinfo alphachar|charnum\n"
#define action_usage_usage "usage: usage command_name\n"
#define action_help_usage "usage: help (use usage for spesific-commands)\n"
#define action_system_usage "usage: system command arg1 arg2 ...\n"
#define action_cd_usage "usage: cd new_directory (can be relative or definite)\n"
#define action_ls_usage "usage: ls directory_to_list (can be omitted to list current directory)\n"
#define action_buffers_use "buffers will modify the buffer_array by allocating or destroying buffers.\n"
#define action_quit_use "quit will exit the shell\n"
#define action_resize_use "resize modifies the size-in-bytes of any given buffer, increase or decrease\n"
#define action_clear_use "clear empties the buffer and sets every byte of it to \\0 \n"
#define action_copy_use "copy will copy one buffer's contents into another, resizing if needed\n"
#define action_load_use "load opens a file and copies its contents into a buffer, unmodified\n"
#define action_write_use "write puts the contents of a buffer into a file\n"
#define action_filter_use "filter will filters a buffer, to prepare it for a crack\n"
#define action_read_use "read displays both the contents and the status of a buffer\n"
#define action_bufferinfo_use "bufferinfo will display the status and size of a buffer\n"
#define action_nullbuffer_use "nullbuffer is a safety function that sets the final null byte\n"
#define action_script_use "script executes any given file as if it were typed into the shell\n"
#define action_quickscript_use "quickscript is the same as script except it does not preparse\n"
#define action_softscript_use "softscript is the same as script except it will stop on soft errors aswell\n"
#define action_quicksoftscript_use "quicksoftscript is a combination of quickscript and softscript\n"
#define action_score_use "score will return a 'english-score' on a buffer from the dictionary\n"
#define action_spaces_use "spaces will attempt to add spaces to a ctext based on dictionary lookups\n"
#define action_wordwrap_use "wordwrap will use spaces and try to wrap the text to the specified length\n"
#define action_loaddict_use "loaddict a cifer-dictionary file into memory for use\n"
#define action_affine_use "affine performs an affine crack by trying to find THE and using affinesolve\n"
#define action_affinesolve_use "affinesolve uses modular arithmitic to solve an affine simultaneous equation\n"
#define action_affinebf_use "affinebf works alike affine except it uses bruteforce to find the solution\n"
#define action_affineencode_use "affineencode will encrypt a buffer with the affine cipher\n"
#define action_affinedecode_use "affinedecode will decrypt a buffer with the affine cipher\n"
#define action_baconencode_use "baconencode encrypts alpha chars using the bacon cipher\n"
#define action_bacondecode_use "bacondecode takes a stream of As and Bs and decrypts using the bacon cipher\n"
#define action_shift_use "shift takes a buffer and performs a vigenere style shift on it\n"
#define action_deltaic_use "deltaic computes the index of coincidence on a buffer\n"
#define action_monoalph_use "monoalph translates a buffer using monoalphabetic substitution\n"
#define action_ctrans_keyinfo_use "ctrans_keyinfo gives information on a columnar transposition key\n"
#define action_c2c_encode_use "c2c_encode encrypts using column to column transposition\n"
#define action_c2c_decode_use "c2c_decode decrypts using column to coulmn transposition\n"
#define action_c2c_bruteforce_use "c2c_bruteforce bruteforces the key for column to column transposition\n"
#define action_r2c_encode_use "r2c_encode encrypts using row to column transposition\n"
#define action_r2c_decode_use "r2c_decode decrypts using row to column transposition\n"
#define action_r2c_bruteforce_use "r2c_bruteforce bruteforces the key for row to column transposition\n"
#define action_c2r_encode_use "c2r_encode encrypts using column to row transposition\n"
#define action_c2r_decode_use "c2r_decode decrypts using column to row transposition\n"
#define action_c2r_bruteforce_use "c2r_bruteforce bruteforces the key for column to row transposition\n"
#define action_fg_use "fg uses frequency analysis to try and guess the characters\n"
#define action_ifg_use "ifg makes an 'identity' freq. graph for any text_size (expected frequencies)\n"
#define action_fa_use "fa performs frequency analysis on a buffer\n"
#define action_digrams_use "digrams reads the ctext and finds the top N digrams\n"
#define action_trigrams_use "trigrams reads the ctext and finds the top N trigrams\n"
#define action_pct_use "pct prints the character table (0 = A, 1 = B...)\n"
#define action_keyb_use "keyb preforms keyword bruteforce\n"
#define action_keye_use "keye encrypts a keyword-cipher using the keyword supplied\n"
#define action_keyd_use "keyd decrypts a keyword-cipher using the keyword supplied \n\
(Because this is a decrypt function the keyword table will be flipped) \n"
#define action_keyt_use "keyt creates a keyword-table\n"
#define action_keytf_use "keytf creates a flipped keyword-table\n"
#define action_polybius_encode_use "polybius will encrypt a text using the polybius cipher\n"
#define action_polybius_decode_use "polybius will decrypt a text using the polybius cipher\n"
#define action_rfbf_use "rfbf bruteforces a railfence cipher\n"
#define action_vigenere_use "vigenere uses deltaic and frequency analysis to crack a vigenere cipher\n"
#define action_mmi_use "mmi computes the modular multiplicative inverse, used in affine ciphers\n"
#define action_gcd_use "gcd computes the greatest common denominator of any number of integers\n"
#define action_coprime_use "coprime determines if two integers are coprime\n"
#define action_charinfo_use "charinfo prints information about a character\n"
#define action_usage_use "usage prints the syntax of a function\n"
#define action_help_use "help lists all the functions\n"
#define action_system_use "system passes a command to /bin/sh\n"
#define action_cd_use "cd changes the current directory\n"
#define action_ls_use "ls lists the content of the current directory\n"
cifer-1.2.0/src/utility.inc 0000644 0001750 0001750 00000002200 11156502713 013722 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
INSERTION_DEFINE(vigenere_column_ic, column_ic_diff)
INSERTION_DEFINE(digram, digram_value)
INSERTION_DEFINE(trigram, trigram_value)
INSERTION_DEFINE(rand_freq, diff)
GET_DEFINE(best, digram, digram_value, int, >)
GET_DEFINE(best, trigram, trigram_value, int, >)
GET_KEY_DEFINE(best, digram, digram_value, int, >)
GET_KEY_DEFINE(best, trigram, trigram_value, int, >)
cifer-1.2.0/src/settings.h 0000644 0001750 0001750 00000002113 11156502713 013540 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define WORD_BUF_SIZE 1024
#define MIN_WORD_SIZE 2
#define DESIGNLANG "English"
#define OPTIMAL_DELTA_IC 1.73 /* Static data on English */
#define AFFINE_WAIT 1 /* How long affine waits before \
* doing utility routines */
#define DEFAULT_BUFFER_SIZE 0
cifer-1.2.0/src/actions_utility.c 0000644 0001750 0001750 00000011462 11156502713 015125 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
#define ACTION_USAGE action_mmi_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_mmi(int argc, char **argv)
{
int value, mod, modo, result, vgcd;
actionu_argchk(2)
actionu_intparse(*(argv) , value)
actionu_intparse(*(argv + 1), mod)
if (value < 1 || mod < 1) actionu_fail()
vgcd = gcd(value, mod);
modo = mod;
if (vgcd != 1)
{
printf("Warning: Cannot MMI if the GCD(value, mod) is not 1. \n");
printf("Taking factor of %i out of args.\n\n", vgcd);
}
printf("MMI: %i (mod %i) \n", value, mod);
if (vgcd != 1)
{
value = value / vgcd;
mod = mod / vgcd;
printf("GCD: %i (mod %i) \n", value, mod);
}
result = modular_multiplicative_inverse(value, mod);
printf("Answer: %i\n", result);
printf("So %i * %i == %i (mod %i) \n", value, result,
modn(value * result, mod), mod);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_gcd_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_gcd(int argc, char **argv)
{
int i, running;
int *numbers;
if (argc < 2) actionu_fail()
numbers = malloc_good( sizeof(int) * argc );
for (i = 0; i < argc; i++)
{
actionu_intparsef(*(argv + i), *(numbers + i), numbers)
if (*(numbers + i) < 1)
{
printf(action_gcd_usage);
return CFSH_COMMAND_HARDFAIL;
}
}
printf("GCD of %i", *(numbers));
running = *(numbers);
for (i = 1; i < argc; i++)
{
printf(", %i", *(numbers + i));
running = gcd(running, *(numbers + i));
}
printf(" is %i \n", running);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_coprime_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_coprime(int argc, char **argv)
{
int a, b, r;
actionu_argchk(2)
actionu_intparse(*(argv) , a)
actionu_intparse(*(argv + 1), b)
if (a < 1 || b < 1) actionu_fail()
r = gcd(a, b);
if (r == 1) printf("%i and %i are coprime. \n", a, b);
else printf("%i and %i are not coprime (gcd %i) \n", a, b, r);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_charinfo_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_charinfo(int argc, char **argv)
{
char ch;
int num;
actionu_argchk(1)
if (strlen(*argv) == 0) actionu_fail()
if (NUMBER_CH(**argv))
{
actionu_intparse(*argv, num)
if (num > 26 || num < 0)
{
printf("mod(%i, 26) = %i \n", num, modn(num, 26));
num = modn(num, 26);
}
ch = ALPHA_TOLOWER(NUMCHAR(num));
printf("The number %i translates to the character %c%c \n", num,
ALPHA_TOUPPER(ch), ch);
}
else if (strlen(*argv) == 1 && ALPHA_CH(**argv))
{
ch = ALPHA_TOLOWER(**argv);
num = CHARNUM(ch);
printf("The character %c%c is also number %i in the 0-26 alphabet.\n",
ALPHA_TOUPPER(ch), ch, num);
}
else
{
actionu_faili()
}
/* Not sure if this is system spesific, or is there a nicer
* way to do this? */
#define binp(a, n) ( ((a) & (n)) == 0 ? '0' : '1' )
#define binap(a) binp(a, 128), binp(a, 64), binp(a, 32), binp(a, 16), \
binp(a, 8), binp(a, 4), binp(a, 2), binp(a, 1)
/* BEWM! */
printf("The character %c (lowercase) is ASCII %3i (decimal) "
"%2x (hex) %c%c%c%c %c%c%c%c (binary)\n",
ch, ch, ch, binap(ch));
/* A little shorter */
#define uch (ALPHA_TOUPPER(ch))
/* Hopefully all the ALPHA_TOUPPER spam will be condensed by the
* Optimiser */
printf("The character %c (uppercase) is ASCII %3i (decimal) "
"%2x (hex) %c%c%c%c %c%c%c%c (binary)\n\n",
uch, uch, uch, binap(uch));
printf("In English, the character %c has frequency: \n", ch);
printf(" decimal probability: %f \n", english_frequency[num] );
printf(" percentage: %.2f%% \n\n", english_frequency[num] * 100);
printf("Bacon for %c: %s \n", ch, bacon_alphabet[num]);
printf("Polybius for %c: %2i \n\n", ch, polybius_grid_25_int[num]);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
cifer-1.2.0/src/vigenere.c 0000644 0001750 0001750 00000005257 11156502713 013513 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
void crack_vigenere(char *intext, int intext_size, char *outtext,
int minb, int maxb)
{
vigenere_column_ic *column_ic;
int i, j, k, h;
int *shift;
double d;
/* min/maxb are _inclusive_ */
h = maxb - minb + 1;
/* Prepare the loop */
if (maxb > intext_size)
{
printf("Checks of length %i requested but ctext is only %i chars long.\n",
maxb, intext_size);
return;
}
if (h <= 0)
{
printf("vigenere: no column-lengths to try.\n");
return;
}
/* Setup */
column_ic = malloc_good( sizeof(vigenere_column_ic) * h );
printf("Attempting Vigenere Cipher Crack %i -> %i keylen\n", minb, maxb);
/* Check all column lengths that we are supposed to */
for (i = 0; i < h; i++)
{
column_ic[i].column_ic_diff = 0;
k = minb + i;
for (j = 0; j < k; j++)
{
column_ic[i].column_ic_diff +=
diff( delta_ic(intext + j, intext_size - j, k), OPTIMAL_DELTA_IC);
}
column_ic[i].column_ic_diff = column_ic[i].column_ic_diff / k;
column_ic[i].column_size = k;
}
/* Sort it */
insertion_sort_vigenere_column_ic(column_ic, h);
/* Prepare to decode... */
h = column_ic[0].column_size;
shift = malloc_good( sizeof(int) * h );
/* The best match should now be in [0], so freq. analyse the columns */
for (i = 0; i < h; i++)
{
*(shift + i) = frequency_analysis(intext + i, intext_size - i, h);
}
/* Do the magic! */
caesar_cipher_dec(intext, intext_size, outtext,
shift, column_ic[0].column_size);
*(outtext + intext_size) = 0;
/* Print out the keyword and deciphered plaintext */
printf("Keyword: ");
for (i = 0; i < h; i++) printf("%c", NUMCHAR(*(shift + i)));
printf(" - ");
for (i = 0; i < h; i++) printf("%i ", *(shift + i));
printf("\n");
d = delta_ic(outtext, intext_size, 1);
printf("Overall Delta IC: %f\n\n", d);
printf("%s\n\n", outtext);
/* Free up... */
free(shift);
}
cifer-1.2.0/src/io.c 0000644 0001750 0001750 00000030154 11156502713 012310 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
char **cfsh_buffers;
int *cfsh_buffer_filters;
int *cfsh_buffer_sizes;
int cfsh_num_buffers;
void buffers_init()
{
/* Simple Initialise. Should only be called once, at startup.
* Not called by any shell command */
cfsh_buffers = NULL;
cfsh_buffer_filters = NULL;
cfsh_buffer_sizes = NULL;
cfsh_num_buffers = 0;
}
void create_buffers(int num)
{
int i, j;
/* Should never happen */
if (num < 0) return;
if (cfsh_num_buffers == 0)
{
if (num != 0)
{
printf("create_buffers: Creating buffers for the first time!\n");
size_buffer_array(num);
printf("create_buffers: initting all %i buffers with %i default length\n",
num, DEFAULT_BUFFER_SIZE);
for (i = 0; i < num; i++) initbuffer(i);
}
else
{
printf("create_buffers: no buffers exist; none created, none cleared\n");
}
}
else if (cfsh_num_buffers > num)
{
printf("create_buffers: buffers %i to %i will be discarded\n",
num, cfsh_num_buffers);
for (i = num; i < cfsh_num_buffers; i++) destroybuffer(i);
printf("create_buffers: reducing array size by %i\n",
cfsh_num_buffers - num);
size_buffer_array(num);
}
else
{
j = cfsh_num_buffers; /* We must find the value now as it will change */
printf("create_buffers: expanding array size by %i\n",
num - cfsh_num_buffers);
size_buffer_array(num);
printf("create_buffers: initting %i new buffers with %i default length\n",
num - j, DEFAULT_BUFFER_SIZE);
for (i = j; i < num; i++) initbuffer(i);
}
}
void size_buffer_array(int n)
{
cfsh_buffers = realloc_good( cfsh_buffers, sizeof(char *) * n );
cfsh_buffer_filters = realloc_good( cfsh_buffer_filters, sizeof(int) * n );
cfsh_buffer_sizes = realloc_good( cfsh_buffer_sizes, sizeof(int) * n );
cfsh_num_buffers = n;
}
void file2buffer(char *name, int buffer_id)
{
int i, original_size;
char *buf;
FILE *file;
struct stat filestats;
clearbuffer(buffer_id);
/* Grab file stats */
if (stat(name, &filestats) == -1)
{
printf("file2buffer: stat failed: %s\n", strerror(errno));
return;
}
/* Check if it's a regular file */
if (!S_ISREG(filestats.st_mode))
{
printf("file2buffer: not a regular file; failed\n");
return;
}
file = fopen(name, "r");
if (file == NULL)
{
printf("file2buffer: fopen failed: %s\n", strerror(errno));
return;
}
flock(fileno(file), LOCK_SH);
/* Save original size incase we need to bail out */
original_size = get_buffer_size(buffer_id);
if (filestats.st_size > get_buffer_size(buffer_id))
{
printf("file2buffer: expanding buffer %i to accomodate file's %li bytes.\n",
buffer_id, filestats.st_size);
resizebuffer(buffer_id, filestats.st_size + 1);
}
i = 0;
buf = get_buffer(buffer_id);
while (feof(file) == 0)
{
*(buf + i) = fgetc(file);
/* Detect error, convert to a null, and finish */
if (*(buf + i) == -1)
{
*(buf + i) = 0;
break;
}
else if (!ASCII_CH(*(buf + i)) && !XSPACE_CH(*(buf + i)))
{
/* trap non ascii stuff, including a null */
printf("file2buffer: error - file is not ASCII, "
"unknown character %2x at byte %i\n",
(unsigned char) *(buf + i), i);
/* bail out, I guess. */
printf("file2buffer: bailing out: emptying buffer\n");
clearbuffer(buffer_id);
/* return buffer to original size, if needed */
if (original_size != get_buffer_size(buffer_id))
{
printf("file2buffer: returning buffer %i to original size %i\n",
buffer_id, original_size);
resizebuffer(buffer_id, original_size);
}
flock(fileno(file), LOCK_UN);
fclose(file);
return;
}
i++;
}
*(buf + i) = 0;
setbuffernull(buffer_id);
printf("file2buffer: loaded %i bytes into buffer %i\n", i - 1, buffer_id);
flock(fileno(file), LOCK_UN);
fclose(file);
}
void buffer2file(char *name, int buffer_id, int mode)
{
int i;
struct stat statbuf;
FILE *file;
i = stat(name, &statbuf);
if (i == -1) i = errno;
file = NULL;
if (i != ENOENT && i != 0)
{
printf("buffer2file: io file error: %s\n", strerror(i));
return;
}
if (i == ENOENT) file = fopen(name, "w");
else if (i == 0 && CFSH_IO_MODE_OVERWRITE) file = fopen(name, "w");
else if (i == 0 && CFSH_IO_MODE_APPEND) file = fopen(name, "a");
else
{
printf("buffer2file: File exists!\n");
return;
}
if (file == NULL)
{
printf("buffer2file: failed to open file: %s\n", strerror(errno));
return;
}
flock(fileno(file), LOCK_EX);
setbuffernull(buffer_id);
i = fputs(get_buffer(buffer_id), file);
if (i == EOF) printf("buffer2file: error in fputs.\n");
if (ferror(file)) printf("buffer2file: warning - outfile error is set.\n");
printf("buffer2file: wrote %i bytes to file.\n",
get_buffer_real_size(buffer_id));
flock(fileno(file), LOCK_UN);
fclose(file);
}
void initbuffer(int buffer_id)
{
get_buffer(buffer_id) = malloc_good( DEFAULT_BUFFER_SIZE + 1 );
get_buffer_size(buffer_id) = DEFAULT_BUFFER_SIZE;
get_buffer_filter(buffer_id) = BUFFER_FILTER_NONE;
clearbuffer(buffer_id);
setbuffernull(buffer_id);
}
void destroybuffer(int buffer_id)
{
free(get_buffer(buffer_id));
get_buffer_size(buffer_id) = 0;
get_buffer_filter(buffer_id) = BUFFER_FILTER_NONE;
}
void resizebuffer(int buffer_id, int newsize)
{
get_buffer(buffer_id) = realloc_good( get_buffer(buffer_id), newsize + 1 );
get_buffer_size(buffer_id) = newsize;
get_buffer_filter(buffer_id) = BUFFER_FILTER_NONE;
clearbuffer(buffer_id);
setbuffernull(buffer_id);
}
int get_buffer_real_size(int buffer_id)
{
/* I wanted to use strnlen, but aparantly that's a GNU Extention and
* compatability sez no. SO the easiest way it to ensure that there is at
* least a \0 on the end and that strlen won't segfault, then strlen
* normally... */
setbuffernull(buffer_id);
return strlen(get_buffer(buffer_id));
}
char *get_filter_text(int mode)
{
switch (mode)
{
case BUFFER_FILTER_ALPHA: return "alpha";
case BUFFER_FILTER_ALPHANUM: return "alphanum";
case BUFFER_FILTER_LALPHA: return "lalpha";
case BUFFER_FILTER_UALPHA: return "ualpha";
case BUFFER_FILTER_FLIPCASE: return "flipcase";
case BUFFER_FILTER_CASEBACON: return "casebacon";
case BUFFER_FILTER_BACON: return "bacon";
case BUFFER_FILTER_NUM: return "num";
case BUFFER_FILTER_ESP: return "esp";
case BUFFER_FILTER_ENL: return "enl";
}
return "none";
}
int get_buffer_filter_fromtext(char *str)
{
if (strcasecmp("alpha", str) == 0)
return BUFFER_FILTER_ALPHA;
else if (strcasecmp("alphanum", str) == 0)
return BUFFER_FILTER_ALPHANUM;
else if (strcasecmp("lalpha", str) == 0)
return BUFFER_FILTER_LALPHA;
else if (strcasecmp("ualpha", str) == 0)
return BUFFER_FILTER_UALPHA;
else if (strcasecmp("flipcase", str) == 0)
return BUFFER_FILTER_FLIPCASE;
else if (strcasecmp("casebacon", str) == 0)
return BUFFER_FILTER_CASEBACON;
else if (strcasecmp("bacon", str) == 0)
return BUFFER_FILTER_BACON;
else if (strcasecmp("num", str) == 0)
return BUFFER_FILTER_NUM;
else if (strcasecmp("esp", str) == 0)
return BUFFER_FILTER_ESP;
else if (strcasecmp("enl", str) == 0)
return BUFFER_FILTER_ENL;
else
return BUFFER_FILTER_NONE;
}
void copybuffer(int buffer_id_1, int buffer_id_2)
{
printf("copybuffer: copying %i to %i...\n", buffer_id_1, buffer_id_2);
if (get_buffer_size(buffer_id_2) < get_buffer_real_size(buffer_id_1))
{
printf("copybuffer: must resize buffer %i to %i bytes\n",
buffer_id_2, get_buffer_real_size(buffer_id_1));
resizebuffer(buffer_id_2, get_buffer_real_size(buffer_id_1));
}
clearbuffer(buffer_id_2);
memcpy(get_buffer(buffer_id_2), get_buffer(buffer_id_1),
get_buffer_real_size(buffer_id_1));
*(get_buffer(buffer_id_2) + get_buffer_real_size(buffer_id_1)) = 0;
setbuffernull(buffer_id_2);
}
void filterbuffer(int buffer_id, int mode)
{
int i, j, t, newsize, newpos;
char ch;
char *buf;
newsize = 0;
buf = get_buffer(buffer_id);
j = get_buffer_real_size(buffer_id);
t = 0;
printf("filterbuffer: applying filter %s...\n", get_filter_text(mode));
for (i = 0; i < j; i++)
{
ch = *(buf + i);
switch (mode)
{
case BUFFER_FILTER_ALPHA: t = ALPHA_CH(ch); break;
case BUFFER_FILTER_ALPHANUM: t = ALPHANUMERIC_CH(ch); break;
case BUFFER_FILTER_LALPHA: t = ALPHA_CH(ch); break;
case BUFFER_FILTER_UALPHA: t = ALPHA_CH(ch); break;
case BUFFER_FILTER_FLIPCASE: t = ALPHA_CH(ch); break;
case BUFFER_FILTER_CASEBACON: t = ALPHA_CH(ch); break;
case BUFFER_FILTER_BACON: t = (CHARNUM(ch) == 0 || CHARNUM(ch) == 1);
break;
case BUFFER_FILTER_NUM: t = NUMBER_CH(ch); break;
case BUFFER_FILTER_ESP: t = !(SPACE_CH(ch) || XSPACE_CH(ch)); break;
case BUFFER_FILTER_ENL: t = !XSPACE_CH(ch); break;
}
if (t) newsize++;
}
newpos = 0;
for (i = 0; i < j; i++)
{
ch = *(buf + i);
switch (mode)
{
case BUFFER_FILTER_ALPHA: t = ALPHA_CH(ch); break;
case BUFFER_FILTER_ALPHANUM: t = ALPHANUMERIC_CH(ch); break;
case BUFFER_FILTER_LALPHA: t = ALPHA_CH(ch);
ch = ALPHA_TOLOWER(ch); break;
case BUFFER_FILTER_UALPHA: t = ALPHA_CH(ch);
ch = ALPHA_TOUPPER(ch); break;
case BUFFER_FILTER_FLIPCASE: t = ALPHA_CH(ch);
ch = ALPHA_FLIP_CASE(ch); break;
case BUFFER_FILTER_CASEBACON: t = ALPHA_CH(ch);
ch = ALPHA_CASEBACON(ch); break;
case BUFFER_FILTER_BACON: t = (CHARNUM(ch) == 0 || CHARNUM(ch) == 1);
ch = ALPHA_TOUPPER(ch); break;
case BUFFER_FILTER_NUM: t = NUMBER_CH(ch); break;
case BUFFER_FILTER_ESP: t = !(SPACE_CH(ch) || XSPACE_CH(ch)); break;
case BUFFER_FILTER_ENL: t = !XSPACE_CH(ch); break;
}
if (t)
{
*(buf + newpos) = ch;
newpos++;
}
}
*(buf + newpos) = 0;
setbuffernull(buffer_id);
t = mode;
switch (mode)
{
case BUFFER_FILTER_LALPHA: t = BUFFER_FILTER_ALPHA; break;
case BUFFER_FILTER_UALPHA: t = BUFFER_FILTER_ALPHA; break;
case BUFFER_FILTER_FLIPCASE: t = BUFFER_FILTER_ALPHA; break;
case BUFFER_FILTER_CASEBACON: t = BUFFER_FILTER_BACON; break;
}
get_buffer_filter(buffer_id) = t;
}
void clearbuffer(int buffer_id)
{
memset(get_buffer(buffer_id), 0, get_buffer_size(buffer_id));
setbuffernull(buffer_id);
}
cifer-1.2.0/src/rf.h 0000644 0001750 0001750 00000001516 11156502713 012315 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
void rf_bf(char *intext, int intext_size, char *outtext,
int minrails, int maxrails);
cifer-1.2.0/src/affine.c 0000644 0001750 0001750 00000017777 11156502713 013151 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
void crack_affine(char *intext, int intext_size, char *outtext)
{
int a, b, i, j;
digram digrams[10];
trigram trigrams[1];
/* Count digrams & trigrams */
count_digrams(intext, intext_size, digrams, 10);
count_trigrams(intext, intext_size, trigrams, 1);
/* See if we can find the right digram, just to double check */
j = 0;
for (i = 0; i < 10; i++)
{
if (digrams[i].digram_ch1 == trigrams[0].trigram_ch1 &&
digrams[i].digram_ch2 == trigrams[0].trigram_ch2)
{
j = i;
}
}
/* Make sure that the first match for each is TH and THE */
if (digrams[j].digram_ch1 != trigrams[0].trigram_ch1 ||
digrams[j].digram_ch2 != trigrams[0].trigram_ch2)
{
printf("\ncrack_affine: Ambiguous failure: Unable to find THE\n");
printf("Affine best digram %c%c: %i, trigram %c%c%c: %i.\n",
NUMCHAR(digrams[j].digram_ch1), NUMCHAR(digrams[j].digram_ch2),
digrams[j].digram_value,
NUMCHAR(trigrams[0].trigram_ch1), NUMCHAR(trigrams[0].trigram_ch2),
NUMCHAR(trigrams[0].trigram_ch3),
trigrams[0].trigram_value);
return;
}
/* Let the ctext for T be x, and H be y, and the plaintext t is 19,
* plaintext H is 7. Unknowns are a and b */
/* 19a + b = x 7a + b = y */
/* CTEXT for T is in digrams[j].digram_ch1 as a CHARNUM */
/* CTEXT for H is in digrams[j].digram_ch2 as a CHARNUM */
printf("Affine best digram %c%c: %i, trigram %c%c%c: %i, let TH == %c%c\n",
NUMCHAR(digrams[j].digram_ch1), NUMCHAR(digrams[j].digram_ch2),
digrams[j].digram_value,
NUMCHAR(trigrams[0].trigram_ch1), NUMCHAR(trigrams[0].trigram_ch2),
NUMCHAR(trigrams[0].trigram_ch3),
trigrams[0].trigram_value,
ALPHA_TOUPPER(NUMCHAR(digrams[j].digram_ch1)),
ALPHA_TOUPPER(NUMCHAR(digrams[j].digram_ch2)) );
affine_solve(digrams[j].digram_ch1, CHARNUM('T'),
digrams[j].digram_ch2, CHARNUM('H'),
&a, &b);
affine_decode(intext, intext_size, outtext, a, b);
/* Set the null byte */
*(outtext + intext_size) = 0;
/* Print the results */
printf("Affine: Deciphered Plaintext (hopefully):\n\n");
printf("%s\n\n", outtext);
}
int affine_solve(int cl_1, int pl_1, int cl_2, int pl_2, int *a, int *b)
{
int i, j;
printf("Solving affine equation: CL => PL: %d => %d (%c), %d => %d (%c)\n",
cl_1, pl_1, NUMCHAR(pl_1), cl_2, pl_2, NUMCHAR(pl_2));
/* ax + b = c (mod d) where X and C are known. */
/* ay + b = e (mod d) where Y and E are known. */
/* X = pl_1; C = cl_1;
* Y = pl_2; E = cl_2; */
/* Step 1) Subtract so that B is eliminated.
* => a*(x-y) = c-e (mod d)
* Step 2) Use the GCD to simplify
* STO => i = gcd(x-y, c-e, d)
* => a*((x-y)/i) = (c-e)/i (mod d/i)
* Step 3) Elmininate (x-y)/i by finding the MMI.
* => a = m(x-y/i, d/i)(c-e/i)
* to get the answer for A!
* now, to sort that number out, modn(a, 26);
* Step 4) Substitute back into both equations...
* => ax + b = c (mod d) (where A is now known)
* Step 5) Subtract from each side, AX
* => b = c - ax (mod d)
* Step 6) Tidy up, and do the same for equ2.
* STO => b = s(c-ax) (mod d)
* STO => b = s(e-ay) (mod d)
*
* Check: That b was the same in both equations.
* That A and 26 are coprime. */
/* Store A from the first completed rearrangement... */
i = gcd(pl_1 - pl_2, gcd(cl_1 - cl_2, 26));
*a = modn(modular_multiplicative_inverse((pl_1 - pl_2)/i, 26/i) *
((cl_1 - cl_2)/i), 26/i);
printf(" Affine simplified solution: %i, looking for real\n", *a);
printf(" ");
/* Because we had to simplify to get a proper MMI, we now have to look for
* the value in mod 26. (There's probably some better way to do this, but
* I don't know it. */
for (j = *a; j < 26; j += (26/i))
{
printf("%i, ", j);
if (IS_COPRIME(j, 26)) *a = j;
}
printf("chosen %i.\n", *a);
/* Store B from the second completed rearrangement... */
*b = modn(cl_1 - (*a * pl_1), 26);
/* Print the information we have found... */
printf(" Affine solution: a = %i, b = %i\n", *a, *b);
/* First check: do the bs match up? */
if (*b != modn(cl_2 - (*a * pl_2), 26))
{
printf(" Affine solution is bad: has two results for B!\n");
return -2;
}
else if (IS_COPRIME(*a, 26))
{
printf(" Affine solution seems OK (a coprime 26)\n");
return 0;
}
else
{
printf(" Affine solution might be bad (a not coprime 26)\n");
return -1;
}
}
void affine_encode(char *intext, int intext_size, char *outtext, int a, int b)
{
int i, ch;
for (i = 0; i < intext_size; i++)
{
ch = CHARNUM(*(intext + i));
if (ch != -1) *(outtext + i) = NUMCHAR(modp((ch * a) + b, 26));
else *(outtext + i) = *(intext + i);
}
}
void affine_decode(char *intext, int intext_size, char *outtext, int a, int b)
{
int i, ch, mmi;
mmi = modular_multiplicative_inverse(a, 26);
for (i = 0; i < intext_size; i++)
{
ch = CHARNUM(*(intext + i));
if (ch != -1) *(outtext + i) = NUMCHAR(modn((ch - b) * mmi, 26));
else *(outtext + i) = *(intext + i);
}
}
void affine_bf(char *intext, int intext_size, char *outtext)
{
int a, b; /* ax + b */
int a_best = 0, b_best = 0;
int score, score_best; /* Dictionary text_tmp scoring */
struct timeval seltime;
char *text_tmp;
fd_set set_stdin, set_stdin_tmp;
score_text_pro_state pro_state;
time_t t1;
/* Select() stuff */
FD_ZERO(&set_stdin);
FD_ZERO(&set_stdin_tmp);
FD_SET(0, &set_stdin); /* 0 is stdin */
seltime.tv_sec = 0;
seltime.tv_usec = 0;
score_best = -1;
score_text_pro_start(intext_size, &pro_state);
/* Temporary location for testing in */
text_tmp = malloc_good(sizeof(char) * intext_size + 1);
*(text_tmp + intext_size) = 0;
printf("Starting affine brute force, press enter to stop...\n");
/* Timing */
t1 = time(NULL);
for (a = 0; ; a++)
{
if (IS_COPRIME(a, 26))
{
for (b = 0; b < 26; b++)
{
affine_decode(intext, intext_size, text_tmp, a, b);
score = score_text_pro(text_tmp, &pro_state);
if (score > score_best)
{
score_best = score;
a_best = a;
b_best = b;
memcpy(outtext, text_tmp, intext_size);
}
if ((time(NULL) - AFFINE_WAIT) > (int) t1) /* Do stuff interval */
{
printf("Curent: %dx + %d\n", a, b);
printf("Best match (%dx + %d): %.50s\n", a_best, b_best, outtext);
set_stdin_tmp = set_stdin;
select(1, &set_stdin_tmp, NULL, NULL, &seltime);
if (FD_ISSET(0, &set_stdin_tmp))
break;
time(&t1);
}
}
if (b != 26) /* If the loop was broken */
break; /* Break the parent */
}
}
printf("Received user interrupt...\n\n");
/* Set the null byte */
*(outtext + intext_size) = 0;
/* Some info */
score_text_pro_print_stats("Affine bruteforce", &pro_state);
printf("Best match (%dx + %d): \n\n", a_best, b_best);
printf("%s\n\n", outtext);
/* Clean up */
score_text_pro_cleanup(&pro_state);
free(text_tmp);
}
cifer-1.2.0/src/frequency_data.c 0000644 0001750 0001750 00000007413 11156502713 014675 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
double english_frequency[26] = { 0.08167, 0.01492, 0.02782, 0.04253, 0.12702,
0.02228, 0.02015, 0.06094, 0.06966, 0.00153,
0.00772, 0.04025, 0.02406, 0.06749, 0.07507,
0.01929, 0.00095, 0.05987, 0.06327, 0.09056,
0.02758, 0.00978, 0.02360, 0.00150, 0.01974,
0.00074 };
void create_identity_frequency_graph(int *frequency_graph, int text_size)
{
int i;
for (i = 0; i < 26; i++)
{
frequency_graph[i] = english_frequency[i] * text_size;
}
}
/* Counts letters 0 -> 26 into the tgt array as [key == letter] => count */
/* Does not support jump/column implementation like frequency_analysis does */
void count_freq(char *text, int input_size, int *tgt)
{
int i, ch;
for (i = 0; i < 26; i++) tgt[i] = 0;
for (i = 0; i < input_size; i++)
{
ch = CHARNUM(*(text + i));
if (ch != -1) tgt[ ch ]++;
}
}
/* Counts digrams, sorts them, and loads the top `tgt_size` into tgt[] */
void count_digrams(char *text, int input_size, digram *tgt, int tgt_size)
{
int i, h, j, ch1, ch2;
digram digrams[26 * 26];
/* Setup */
h = 0;
for (i = 0; i < 26; i++) for (j = 0; j < 26; j++)
{
digrams[h].digram_ch1 = i;
digrams[h].digram_ch2 = j;
digrams[h].digram_value = 0;
h++;
}
/* Count */
h = input_size - 1;
for (i = 0; i < h; i++)
{
ch1 = CHARNUM(*(text + i));
ch2 = CHARNUM(*(text + i + 1));
if (ch1 != -1 && ch2 != -1) digrams[((ch1 * 26) + ch2)].digram_value++;
}
/* No point sorting if we only want one */
if (tgt_size == 1)
{
tgt[0] = best_digram(digrams, 26 * 26);
return;
}
/* Sort */
insertion_sort_digram(digrams, 26 * 26);
/* Grab the top few */
j = min(tgt_size, 26 * 26);
for (i = 0; i < j; i++)
{
h = (26 * 26) - 1 - i;
tgt[i] = digrams[h];
}
}
void count_trigrams(char *text, int input_size, trigram *tgt, int tgt_size)
{
int i, h, j, k, ch1, ch2, ch3;
trigram trigrams[26 * 26 * 26]; /* You know something's wrong when one stack
* frame is 70KB. =P */
/* Setup */
h = 0;
for (i = 0; i < 26; i++) for (j = 0; j < 26; j++) for (k = 0; k < 26; k++)
{
trigrams[h].trigram_ch1 = i;
trigrams[h].trigram_ch2 = j;
trigrams[h].trigram_ch3 = k;
trigrams[h].trigram_value = 0;
h++;
}
/* Count */
h = input_size - 2;
for (i = 0; i < h; i++)
{
ch1 = CHARNUM(*(text + i));
ch2 = CHARNUM(*(text + i + 1));
ch3 = CHARNUM(*(text + i + 2));
if (ch1 != -1 && ch2 != -1 && ch3 != -1)
trigrams[((ch1 * (26 * 26)) + (ch2 * 26) + ch3)].trigram_value ++;
}
/* Better this way */
if (tgt_size == 1)
{
tgt[0] = best_trigram(trigrams, 26 * 26 * 26);
return;
}
/* Sort */
insertion_sort_trigram(trigrams, 26 * 26 * 26);
/* Grab the top few */
j = min(tgt_size, 26 * 26 * 26);
for (i = 0; i < j; i++)
{
h = (26 * 26 * 26) - 1 - i;
tgt[i] = trigrams[h];
}
}
cifer-1.2.0/src/actions_shell.c 0000644 0001750 0001750 00000014671 11156502713 014536 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
#define ACTION_USAGE action_quit_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_quit(int argc, char **argv)
{
actionu_argless()
return CFSH_BREAK_LOOP;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_usage_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_usage(int argc, char **argv)
{
actionu_argchk(1)
printf("%s%s", cfsh_get_use(*argv), cfsh_get_usage(*argv));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
/* -- A very rudimentary `more' */
/* Checks if we can start a line; blocks if we can't */
void action_help_lnblk(int *lnc, int nln)
{
if (*lnc == nln)
{
printf(" -- Press enter for more -- ");
while (fgetc(stdin) != '\n'); /* note ; at end for do-nuffing loop */
*lnc = min(4, nln); /* Four lines are 'kept' */
}
(*lnc)++;
}
/* Echos a potentially multiline-string out. */
void action_help_strpr(char *str, int *lnc, int nln)
{
int i, j;
char *str2;
char *stru;
j = strlen(str);
str2 = malloc_good( j + 1 );
/* Str2 is a copy we can mess with */
memcpy(str2, str, j);
str2[j] = 0;
/* stru is a pointer to the start of the next line, ie.
* the last line we printed + 1 */
stru = str2;
for (i = 0; i < j; i++)
{
if (str[i] == '\n')
{
action_help_lnblk(lnc, nln);
str2[i] = 0;
printf("%s\n", stru);
stru = str2 + i + 1;
}
}
if (stru != (str2 + j)) printf("%s", stru);
free(str2);
}
/* Just a printf("\n"); style thing */
void action_help_nl(int *lnc, int nln)
{
action_help_lnblk(lnc, nln);
printf("\n");
}
#define cfsh_func(n, f) \
if (&f != last_command) \
{ \
if (aliases_print) printf("\n"); \
action_help_nl(&lnc, lines); \
action_help_strpr( f ## _use, &lnc, lines ); \
action_help_strpr( f ## _usage, &lnc, lines ); \
\
last_command = &f; \
aliases_print = 0; \
} \
else \
{ \
if (!aliases_print) \
{ \
action_help_lnblk(&lnc, lines); \
printf("aliases: %s", n); \
aliases_print = 1; \
} \
else \
{ \
printf(", %s", n); \
} \
}
#define ACTION_USAGE action_help_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_help(int argc, char **argv)
{
cfsh_command last_command;
int aliases_print, lines, lnc;
struct winsize win;
/* By default we go for 22, 2 less than the default height (24) */
lines = 22;
/* Figure out how many lines there are */
/* Subtract 2 to leave space for any straggling lines, eg aliases */
if (ioctl(fileno(stdout), TIOCGWINSZ, &win) != -1)
{
if (win.ws_row != 0) lines = win.ws_row - 2;
}
actionu_argless()
aliases_print = 0;
lnc = 0;
last_command = NULL;
#include "command.inc"
if (aliases_print) action_help_nl(&lnc, lines);
action_help_nl(&lnc, lines);
action_help_strpr("type usage for more information.\n",
&lnc, lines);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#undef cfsh_func
#define ACTION_USAGE action_system_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_system(int argc, char **argv)
{
int ret, retr;
char *cmd;
/* TODO: this whole thing is an ugly hack, cfsh_commandline and all */
/* Use the untainted copy but cut off the first bit */
cmd = cfsh_commandline;
/* If argc is -1, its one of the ones below calling me,
* so don't trim the first bit */
if (argc != -1) while (*cmd != ' ' && *cmd != '\0') cmd++;
if (cmd == '\0' || strtlen(cmd) == 0)
{
printf("no command specified for system\n");
return CFSH_COMMAND_HARDFAIL;
}
ret = system(cmd);
/* Todo, fixme! (System spesific) */
retr = (ret >> 8) & 0xFF;
if (ret == -1) printf("system returned -1, failed.\n");
else printf("shell exited %i\n", retr);
return (ret == 0 ? CFSH_OK : CFSH_COMMAND_SOFTFAIL);
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_cd_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_cd(int argc, char **argv)
{
int result;
actionu_argchk(1)
result = chdir(*argv);
if (result != 0)
{
perror("chdir");
actionu_faili()
}
printf("changed directory successfully\n");
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_ls_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_ls(int argc, char **argv)
{
/* Just send to system ;) */
action_system(-1, NULL);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
cifer-1.2.0/src/interface.h 0000644 0001750 0001750 00000002274 11156502713 013650 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
void print_digrams(digram *input, int size);
void print_trigrams(trigram *input, int size);
/* Format and print letter frequencies. Takes an int array[size] of
* frequencies */
void print_freq(int *freq, int *idfreq);
void print_setup_width(int *width, int *m);
void print_count_width(int *freq, int *width, int *m);
void print_finalise_width(int *width, int *m);
/* Print a table of letters mapped to their numeric equivalents */
void print_char_table(void);
cifer-1.2.0/src/interface.c 0000644 0001750 0001750 00000005606 11156502713 013645 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
char *intext;
int intext_size;
void print_freq(int *freq, int *idfreq)
{
int i, m;
int width[26];
printf("Char | CHARNUM | Frequency | Identity Frequency\n\n");
print_setup_width(width, &m);
print_count_width(freq, width, &m);
print_count_width(idfreq, width, &m);
print_finalise_width(width, &m);
printf("C|");
for (i = 0; i < 26; i++) printf("%*c|", width[i], NUMCHAR(i));
printf("\n");
printf("N|");
for (i = 0; i < 26; i++) printf("%*i|", width[i], i);
printf("\n");
printf("F|");
for (i = 0; i < 26; i++) printf("%*i|", width[i], freq[i]);
printf("\n");
printf("I|");
for (i = 0; i < 26; i++) printf("%*i|", width[i], idfreq[i]);
printf("\n\n");
}
void print_setup_width(int *width, int *m)
{
int i;
*m = 0;
for (i = 0; i < 26; i++) width[i] = (i < 10 ? 1 : 2);
}
void print_count_width(int *freq, int *width, int *m)
{
int i, w;
for (i = 0; i < 26; i++)
{
if (freq[i] < 10 && i < 10) w = 1;
else if (freq[i] < 100) w = 2;
else if (freq[i] < 1000) w = 3;
else w = 4;
if (w > *m) *m = w;
if (w > width[i]) width[i] = w;
}
}
void print_finalise_width(int *width, int *m)
{
int i;
if (*m <= 2)
{
/* Then we can afford to have them all at 2. It looks nicer */
for (i = 0; i < 26; i++) width[i] = 2;
}
}
void print_char_table(void)
{
int i;
printf("Char | CHARNUM\n\n");
printf("C|");
for (i = 0; i < 26; i++) printf("%2c|", NUMCHAR(i));
printf("\n");
printf("N|");
for (i = 0; i < 26; i++) printf("%2i|", i);
printf("\n\n");
}
void print_digrams(digram *input, int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("%c%c: %d\n", NUMCHAR(input[i].digram_ch1),
NUMCHAR(input[i].digram_ch2),
input[i].digram_value);
}
}
void print_trigrams(trigram *input, int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("%c%c%c: %d\n", NUMCHAR(input[i].trigram_ch1),
NUMCHAR(input[i].trigram_ch2),
NUMCHAR(input[i].trigram_ch3),
input[i].trigram_value);
}
}
cifer-1.2.0/src/macros.h 0000644 0001750 0001750 00000004306 11156502713 013172 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
#define max(X, Y) ((X) > (Y) ? (X) : (Y))
#define diff(X, Y) ((X) > (Y) ? ((X) - (Y)) : ((Y) - (X)))
#define modp(X, B) ((X) % (B))
#define modn(X, B) ((X) % (B)) + (((X) % (B)) < 0 ? (B) : 0)
#define ASCII_CH(ch) (ch >= 32 && ch <= 128)
#define ALPHAL_CH(ch) (ch >= 97 && ch <= 122)
#define ALPHAH_CH(ch) (ch >= 65 && ch <= 90)
#define NUMBER_CH(ch) (ch >= 48 && ch <= 57)
#define ALPHA_CH(ch) (ALPHAL_CH(ch) || ALPHAH_CH(ch))
#define ALPHANUMERIC_CH(ch) (ALPHA_CH(ch) || NUMBER_CH(ch))
#define SPACE_CH(ch) (ch == 32)
#define XSPACE_CH(ch) (ch == 9 || ch == 10 || ch == 13 || ch == 127)
#define QUOTE_CH(ch) (ch == 39 || ch == 34)
#define ESCAPE_CH(ch) (ch == 92)
#define ALPHA_TOUPPER(ch) (ALPHAL_CH(ch) ? ch - 32 : ch)
#define ALPHA_TOLOWER(ch) (ALPHAH_CH(ch) ? ch + 32 : ch)
#define ALPHA_FLIP_CASE(ch) ( ALPHAL_CH(ch) ? ch - 32 : \
(ALPHAH_CH(ch) ? ch + 32 : ch) )
#define ALPHA_CASEBACON(ch) (ALPHAH_CH(ch) ? 'A' : \
(ALPHAL_CH(ch) ? 'B' : ch) )
#define IS_NEWLINE(ch) (ch == 10)
#define CHARNUM(ch) (ALPHAL_CH(ch) ? ch - 97 : \
(ALPHAH_CH(ch) ? ch - 65 : -1) )
#define NUMCHAR(i) (i + 97)
#define NUMCHARNUM(ch) (NUMBER_CH(ch) ? ch - 48 : -1)
#define NUMNUMCHAR(i) (i + 48)
cifer-1.2.0/src/keyword.c 0000644 0001750 0001750 00000016423 11156502713 013370 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
void keyword_bruteforce(char *intext, int intext_size, char *outtext)
{
char *j, *e, *best, statusbuf[75];
int len, score, best_score, temp_table[26];
int i, p, lastp, l, lastl, lastplen;
struct timeval seltime;
fd_set stdset, stdset_temp;
score_text_pro_state pro_state;
/* Select() stuff */
FD_ZERO(&stdset);
FD_SET(0, &stdset); /* 0 is stdin */
/* Zero these values for a non-blocking check */
seltime.tv_sec = 0;
seltime.tv_usec = 0;
printf("keyword_bruteforce: Trying to find Keyword Cipher from the dict.\n");
/* Dict will have been opened by action.c */
e = *(dict_pointer + (26 * 26)); /* The end of the dictionary */
/* Setup Dictionary_pro */
score_text_pro_start(intext_size, &pro_state);
/* Null termination */
*(outtext + intext_size) = 0;
/* Prepare */
best = 0;
best_score = -1;
lastp = -1;
lastl = -1;
lastplen = 0;
printf("Press enter at any time to stop the brute force and use the last ");
printf("best keyword.\n");
for (j = dict; j < e; j += len + 1)
{
len = strlen(j);
l = CHARNUM(*j);
p = (l * 26) + CHARNUM(*(j + 1));
if (l != lastl)
{
if (lastl != -1)
{
keyword_table_preflipped(best, strlen(best), temp_table);
keyword_translate(intext, intext_size, outtext, temp_table);
/* We have 80 - lastplen chars left. Spare 5 for ... \0, \n and ) */
snprintf(statusbuf, 75 - lastplen, " (best so far: %i, %s: %s",
best_score, best, outtext);
/* Filter anything that will break our formatting */
for (i = 0; i < (74 - lastplen); i++)
if (XSPACE_CH(*(statusbuf + i)))
*(statusbuf + i) = ' ';
*(statusbuf + 75 - lastplen) = 0;
/* Write out the now trimmed string (with the suffix blah...) \n */
printf("%s...)", statusbuf);
stdset_temp = stdset;
select(1, &stdset_temp, NULL, NULL, &seltime);
if (FD_ISSET(0, &stdset_temp))
break;
}
printf("\n");
fflush(stdout);
lastplen = 0;
}
if (p != lastp)
{
printf("|");
fflush(stdout);
lastplen++;
}
lastl = l;
lastp = p;
keyword_table_preflipped(j, len, temp_table);
keyword_translate(intext, intext_size, outtext, temp_table);
score = score_text_pro(outtext, &pro_state);
if (score > best_score)
{
best = j;
best_score = score;
}
}
/* Finish off the final bar */
printf("\n\n");
/* Some Pro_check finish, stats and cleanup */
score_text_pro_print_stats("keyword bruteforce", &pro_state);
score_text_pro_cleanup(&pro_state);
/* Now retrieve best */
keyword_table_preflipped(best, strlen(best), temp_table);
keyword_translate(intext, intext_size, outtext, temp_table);
keyword_table_flip(temp_table);
keyword_print_info(outtext, best, temp_table, "(bruteforce) decode");
}
/* This function fills out an int array[26] from the keyword */
/* in this table, the KEY is the plaintext. */
void keyword_table(char *keyword, int keyword_length, int *table)
{
int i, j, t;
int used_letters[26];
/* Setup. */
for (i = 0; i < 26; i++) used_letters[i] = 0;
t = 0;
/* Copy the keyword in, removing duplicate letters */
for (i = 0; i < keyword_length; i++)
{
j = CHARNUM(*(keyword + i));
if (!used_letters[j])
{
table[t] = j;
t++;
used_letters[j] = 1;
}
}
/* Fill the remainder of the table. */
for (i = t; i < 26; i++)
{
/* Find an unused letter */
for (j = 0; j < 26; j++)
{
if (!used_letters[j])
{
used_letters[j] = 1;
table[i] = j;
break; /* Break the J loop only. */
}
}
}
}
void keyword_table_preflipped(char *keyword, int keyword_length, int *table)
{
int i, j, t;
int used_letters[26];
/* Setup. */
for (i = 0; i < 26; i++) used_letters[i] = 0;
t = 0;
/* Copy the keyword in, removing duplicate letters */
for (i = 0; i < keyword_length; i++)
{
j = CHARNUM(*(keyword + i));
if (!used_letters[j])
{
table[j] = t;
t++;
used_letters[j] = 1;
}
}
/* Fill the remainder of the table. */
for (i = t; i < 26; i++)
{
/* Find an unused letter */
for (j = 0; j < 26; j++)
{
if (!used_letters[j])
{
used_letters[j] = 1;
table[j] = i;
break; /* Break the J loop only. */
}
}
}
}
/* This takes a array[plaintext] => ciphertext and makes it into
* array[ciphertext] => plaintext */
void keyword_table_flip(int *table)
{
int i;
int temp[26];
/* 1) copy table into temp */
for (i = 0; i < 26; i++) temp[i] = table[i];
/* 2) now flip keys and values... */
for (i = 0; i < 26; i++) table[temp[i]] = i;
}
int keyword_check(char *keyword, int key_size)
{
int i;
/* Check the keyword is ok! */
for (i = 0; i < key_size; i++)
{
if (!ALPHA_CH(*(keyword + i)))
{
return -1;
}
}
return 0;
}
/* This function will take a keyword and decode a keyword cipher
* Note the intext and outtext, that's because we have to bruteforce
* this routine and memcpy or a restoring-text for_loop would take
* about 80% of the time up!!! (atleast on my pc) */
void keyword_translate(char *intext, int intext_size, char *outtext, int *table)
{
int i, c;
char o;
/* Translate... */
for (i = 0; i < intext_size; i++)
{
o = *(intext + i);
c = CHARNUM(o);
if (c != -1) o = NUMCHAR( table[c] );
*(outtext + i) = o;
}
}
void keyword_table_copy(int *dest, int *source)
{
int i;
for (i = 0; i < 26; i++) dest[i] = source[i];
}
void keyword_single(char *intext, int intext_size, char *outtext,
char *keyword, int key_size, int flip)
{
int table[26], otable[26];
keyword_table(keyword, key_size, table);
keyword_table_copy(otable, table);
if (flip) keyword_table_flip(table);
keyword_translate(intext, intext_size, outtext, table);
*(outtext + intext_size) = 0;
keyword_print_info(outtext, keyword, otable,
(flip ? "decode" : "encode"));
}
void keyword_print_keyinfo(int *table)
{
int i;
printf("Plaintext Char | Ciphertext Char\n");
printf("P|");
for (i = 0; i < 26; i++) printf("%2c|", NUMCHAR(i));
printf("\n");
printf("C|");
for (i = 0; i < 26; i++) printf("%2c|", NUMCHAR(table[i]));
printf("\n\n");
}
void keyword_print_info(char *text, char *keyword,
int *table, char *dirstring)
{
printf("Keyword Cipher %s using keyword %s: \n\n", dirstring, keyword);
keyword_print_keyinfo(table);
printf("%s\n\n", text);
}
cifer-1.2.0/src/rf.c 0000644 0001750 0001750 00000016101 11156502713 012304 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
void rf_bf(char *intext, int intext_size, char *outtext,
int minrails, int maxrails)
{
int i, j, k, l, m, numloops, currails, currwl, currs, spaces1, spaces2;
int *wl, *repeats, *repeats_rem, **chcount;
int score, best_score, best_rails;
char *ptext;
score_text_pro_state pro_state;
/* Setup */
maxrails++; /* The code below takes maxrails as the maximum exclusive,
as its easier that way. Lets add one to include it */
numloops = maxrails - minrails;
if (numloops < 1) return;
if (minrails < 2) return;
wl = malloc_good( sizeof(int) * numloops );
repeats = malloc_good( sizeof(int) * numloops );
repeats_rem = malloc_good( sizeof(int) * numloops );
chcount = malloc_good( sizeof(int *) * numloops );
for (i = 0; i < numloops; i++)
*(chcount + i) = malloc_good( sizeof(int) * (i + minrails) );
ptext = malloc_good( intext_size + 1 );
*(ptext + intext_size) = 0;
best_rails = 0;
best_score = -1;
/* Makes -O2 happy =) */
spaces1 = 0;
spaces2 = 0;
currs = 0;
score_text_pro_start(intext_size, &pro_state);
/* End setup */
/* Wavelength, for each rails */
for (i = 0; i < numloops; i++)
*(wl + i) = (minrails + i - 1) * 2;
/* Check that its not a too big max_rail */
if (*(wl + numloops - 1) > intext_size)
{
printf("Max Rail (%i) wavelength %i is bigger than text size %i!\n",
maxrails - 1, *(wl + numloops - 1), intext_size);
/* Free up */
for (i = 0; i < numloops; i++) free( *(chcount + i) );
free(chcount);
free(wl);
free(repeats);
free(repeats_rem);
free(ptext);
/* Flee */
return;
}
/* How many times the wave repeats, and the amount of the wave left over,
for each rails */
for (i = 0; i < numloops; i++)
{
*(repeats_rem + i) = modp(intext_size, *(wl + i));
*(repeats + i) = (intext_size - *(repeats_rem + i)) / *(wl + i);
}
/* chcount holds the count of chars for [currails - minrails][line] */
for (i = 0; i < numloops; i++)
{
/* Precache */
k = *(repeats + i);
l = k * 2;
/* The first and last line of each wave in rails has 1 ptext char */
*(*(chcount + i)) = k; /* First */
*(*(chcount + i) + minrails + i - 1) = k; /* Last */
/* The others have 2 ptext chars */
for (j = 1; j < (minrails + i - 1); j++)
*(*(chcount + i) + j) = l;
/* Handle that remainder! */
l = *(repeats_rem + i);
for (k = 0; k < l; k++)
{
/* This increments k until it goes past i (rails) and then makes it
* go back down; (k - i) = num gone past rail, i - (k - i) = going
* back up the pattern; simplify to 2i - k */
m = (k >= (minrails + i) ? (((minrails + i - 1) * 2) - k) : k);
(*(*(chcount + i) + m))++;
}
}
printf("Railfence Bruteforce: Starting %i loops, %i => %i\n",
numloops, minrails, maxrails - 1);
/* Go pwn that cifaa */
for (currails = minrails; currails < maxrails; currails++)
{
/* Precache this from our array */
currwl = *(wl + currails - minrails);
/* Our chcount for this rail is chcount[currails - minrails][] */
/* J is the end of the rail; I is the pointer in the ctext, k is
* rail num; L is the current target. */
i = 0;
j = 0;
k = -1; /* This will be incremented to 0 straight away */
l = 0;
while (i < intext_size)
{
/* This should happen at the end of each rail */
if (j == i)
{
/* Work out when the next one ends */
k++;
j = i + *(*(chcount + currails - minrails) + k);
/* Find out the two alternating spaces for this rail and setup
* the target start (l). */
if (k == 0 || k == (currails - 1))
{
spaces1 = currwl;
spaces2 = currwl;
}
else
{
spaces2 = k * 2;
spaces1 = currwl - spaces2;
}
/* Flag the current spaces as (none); then set l to the init position */
currs = -1;
l = k;
}
/* Increment l; but only if it currs != -1 (none) */
if (currs == 1) l += spaces1;
else if (currs == 2) l += spaces2;
/* Place that ptext char where it belongs! */
*(ptext + l) = *(intext + i);
if (l > intext_size)
{
printf("Fatal Error:\n");
printf("ptext-bust | rail: %i/%i, j: %i, i: %i, l: %i, s: %i\n",
k, currails, j, i, l, intext_size);
/* Free up */
for (i = 0; i < numloops; i++) free( *(chcount + i) );
free(chcount);
free(wl);
free(repeats);
free(repeats_rem);
free(ptext);
return;
}
/* Setup the next increment: if its spaces2 or none - set it to spaces1;
* else make it spaces2 */
if (currs == 1) currs = 2;
else currs = 1;
i++;
}
/* Just in case */
*(ptext + intext_size) = 0;
/* Now score that text */
score = score_text_pro(ptext, &pro_state);
if (score > best_score)
{
best_score = score;
best_rails = currails;
memcpy(outtext, ptext, intext_size);
*(outtext + intext_size) = 0; /* Be sure about \0 */
}
}
/* Print some info */
currwl = *(wl + best_rails - minrails);
printf("Railfence Bruteforce: Best Match %i:%i (%i)\n\n",
best_rails, currwl, best_score);
/* Sorta like the loop above, but this prints an awesome pattern */
for (i = 0; i < best_rails; i++)
{
if (i == 0 || i == (best_rails - 1))
{
spaces1 = currwl;
spaces2 = currwl;
}
else
{
spaces2 = i * 2;
spaces1 = currwl - spaces2;
}
l = i;
currs = 1;
/* And the rest */
for (k = 0; k < 60; k++)
{
if (k == l)
{
if (currs == 1) l += spaces1;
else if (currs == 2) l += spaces2;
if (currs == 1) currs = 2;
else currs = 1;
printf("X");
}
else
{
printf(".");
}
}
printf(" %2i: %2i, %2i\n", i, spaces1, spaces2);
}
printf("\n");
printf("ptext_best: \n\n");
printf("%s\n\n", outtext);
/* Free up */
for (i = 0; i < numloops; i++) free( *(chcount + i) );
free(chcount);
free(wl);
free(repeats);
free(repeats_rem);
free(ptext);
}
cifer-1.2.0/src/shell.h 0000644 0001750 0001750 00000002567 11156502713 013024 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define CFSH_READ_MODE_PARSECHECK 1
#define CFSH_READ_MODE_EXECUTE_SF 2
#define CFSH_READ_MODE_EXECUTE_HF 3
#define CFSH_READ_MODE_INTERACTIVE 4
#define CFSH_COMMAND_PARSEFAIL -6
#define CFSH_COMMAND_SOFTFAIL -7
#define CFSH_COMMAND_HARDFAIL -8
#define CFSH_OK 0
#define CFSH_BREAK_LOOP 99
extern char *cfsh_commandline;
void cfsh_init();
void cfsh_autoinit();
int cfsh_read(FILE *read, int mode);
void cfsh_scriptfile(char *name, int preparse, int softfail);
int cfsh_line(char *input, int mode);
void cifer_header();
#define cfsh_interactive() cfsh_read(stdin, CFSH_READ_MODE_INTERACTIVE)
cifer-1.2.0/src/polybius.h 0000644 0001750 0001750 00000001634 11156502713 013555 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
void polybius_encode(char *intext, int intext_size, char *outtext);
void polybius_decode(char *intext, int intext_size, char *outtext);
extern int polybius_grid_25_int[26];
cifer-1.2.0/src/actions_ciphers.c 0000644 0001750 0001750 00000060645 11156502713 015066 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
#define ACTION_USAGE action_affine_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_affine(int argc, char **argv)
{
int buffer_in, buffer_out;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_copysize(buffer_in, buffer_out);
actionu_bufferout_fn()
crack_affine(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out));
actionu_copysize(buffer_in, buffer_out);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_affinesolve_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_affinesolve(int argc, char **argv)
{
int ct1, pt1, ct2, pt2, a, b;
actionu_argchk(4)
actionu_intparse_char( *(argv), ct1 )
actionu_intparse_char( *(argv + 1), pt1 )
actionu_intparse_char( *(argv + 2), ct2 )
actionu_intparse_char( *(argv + 3), pt2 )
affine_solve(ct1, pt1, ct2, pt2, &a, &b);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_affinebf_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_affinebf(int argc, char **argv)
{
int buffer_in, buffer_out;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_copysize(buffer_in, buffer_out);
actionu_bufferout_fn()
affine_bf(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out));
actionu_copysize(buffer_in, buffer_out);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_affineencode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_affineencode(int argc, char **argv)
{
int buffer_in, buffer_out, a, b;
actionu_argchk(4)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_intparse(*(argv + 2), a)
actionu_intparse(*(argv + 3), b)
actionu_bufferout_fn()
affine_encode(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), a, b);
actionu_copysize(buffer_in, buffer_out);
printf("affineencode: encrypting using the affine cipher, %ix + %i\n\n",
a, b);
printf("%s\n\n", get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_affinedecode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_affinedecode(int argc, char **argv)
{
int buffer_in, buffer_out, a, b;
actionu_argchk(4)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_intparse(*(argv + 2), a)
actionu_intparse(*(argv + 3), b)
actionu_bufferout_fn()
affine_decode(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), a, b);
actionu_copysize(buffer_in, buffer_out);
printf("affinedecode: decrypting using the affine cipher, %ix + %i\n\n",
a, b);
printf("%s\n\n", get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_baconencode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_baconencode(int argc, char **argv)
{
int buffer_in, buffer_out;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
if (get_buffer_real_size(buffer_in) * 5 > get_buffer_size(buffer_out))
{
printf("auto expanding output buffer %i to %i bytes (just in case).\n",
buffer_out, get_buffer_real_size(buffer_in) * 5);
resizebuffer(buffer_out, get_buffer_real_size(buffer_in) * 5);
}
actionu_bufferout_fn()
bacon_encode(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_bacondecode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_bacondecode(int argc, char **argv)
{
int buffer_in, buffer_out;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
if (get_buffer_real_size(buffer_in) > get_buffer_size(buffer_out))
{
printf("auto expanding output buffer %i to %i bytes (just in case).\n",
buffer_out, get_buffer_real_size(buffer_in));
resizebuffer(buffer_out, get_buffer_real_size(buffer_in));
}
actionu_bufferout_fn()
bacon_decode(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_shift_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_shift(int argc, char **argv)
{
int i, j, k, l, buffer_in, buffer_out, direction;
char ch;
int *shift;
char *dirstr;
if (argc < 4) actionu_fail()
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
if (strcasecmp(*(argv + 2), "forwards") == 0 ||
strcasecmp(*(argv + 2), "f") == 0)
{
direction = 1;
dirstr = "forwards";
}
else if (strcasecmp(*(argv + 2), "backwards") == 0 ||
strcasecmp(*(argv + 2), "b") == 0)
{
direction = 0;
dirstr = "backwards";
}
else
{
printf(action_shift_usage);
return CFSH_COMMAND_HARDFAIL;
}
if (ALPHA_CH(*(*(argv + 3))))
{
for (i = 3, j = 0; i < argc; i++)
{
l = strlen(*(argv + i));
for (k = 0; k < l; k++)
{
ch = *(*(argv + i) + k);
if (ALPHA_CH(ch)) j++;
else if (!SPACE_CH(ch))
{
printf(action_shift_usage);
return CFSH_COMMAND_HARDFAIL;
}
}
}
shift = malloc_good( sizeof(int) * j );
for (i = 3, j = 0; i < argc; i++)
{
l = strlen(*(argv + i));
for (k = 0; k < l; k++)
{
ch = *(*(argv + i) + k);
if (ALPHA_CH(ch))
{
*(shift + j) = CHARNUM(ch);
j++;
}
}
}
}
else
{
shift = malloc_good( sizeof(int) * (argc - 3) );
for (i = 3, j = 0; i < argc; i++, j++)
{
actionu_intparsef(*(argv + i), *(shift + j), shift)
*(shift + j) = modn( *(shift + j) , 26);
}
}
actionu_bufferout_fn()
if (direction) caesar_cipher_enc(get_buffer(buffer_in),
get_buffer_real_size(buffer_in),
get_buffer(buffer_out),
shift, j);
else caesar_cipher_dec(get_buffer(buffer_in),
get_buffer_real_size(buffer_in),
get_buffer(buffer_out),
shift, j);
actionu_copysize(buffer_in, buffer_out);
printf("shift: shifting %s by %c", dirstr, NUMCHAR(*(shift)));
for (i = 1; i < j; i++) printf("%c", NUMCHAR(*(shift + i)));
printf("\n\n");
printf("%s\n\n", get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_monoalph_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_monoalph(int argc, char **argv)
{
int i, j, l, ch, buffer_in, buffer_out, szc, direction;
int translation[26];
char *dirstr;
actionu_argchk(4)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
if (strcasecmp(*(argv + 2), "encrypt") == 0 ||
strcasecmp(*(argv + 2), "e") == 0)
{
direction = 1;
dirstr = "encrypting";
}
else if (strcasecmp(*(argv + 2), "decrypt") == 0 ||
strcasecmp(*(argv + 2), "d") == 0)
{
direction = 0;
dirstr = "decrypting";
}
else
{
printf(action_monoalph_usage);
return CFSH_COMMAND_HARDFAIL;
}
szc = strlen(*(argv + 3));
if (strtlens(*(argv + 3), szc) != 26)
{
printf("monoalphabetic translation alphabet should be 26 chars long\n");
printf(action_monoalph_usage);
return CFSH_COMMAND_HARDFAIL;
}
for (i = 0; i < 26; i++) translation[i] = -1;
j = (szc - strrights(*(argv + 3), szc));
for (i = strlefts(*(argv + 3), szc), l = 0; i < j; i++, l++)
{
ch = CHARNUM(*(*(argv + 3) + i));
if (ch == -1) break;
if (direction) translation[l] = ch;
else translation[ch] = l;
}
for (i = 0; i < 26; i++) if (translation[i] == -1)
{
printf("invalid character in monoalphabetic translation alphabet");
printf(action_monoalph_usage);
return CFSH_COMMAND_HARDFAIL;
}
printf("monoalph: %s with the translation alphabet ", dirstr);
for (i = 0; i < 26; i++) printf("%c", NUMCHAR(translation[i]));
printf("\n\n");
actionu_bufferout_fn()
monoalph_substitute(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), translation);
actionu_copysize(buffer_in, buffer_out);
printf("%s\n\n", get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
int actionu_ctrans_keyword_parse(int argc, char **argv,
int **key, int *key_size)
{
int i;
size_t sz;
char *ch;
/* Start by trying to find out if it is a number key or an alpha one */
sz = strlen(*(argv));
ch = (*(argv) + strlefts(*(argv), sz));
if (NUMBER_CH(*ch))
{
/* Then we can try and parse the whole thing into a key */
*key_size = argc;
*key = malloc_good(sizeof(int) * argc);
for (i = 0; i < argc; i++)
{
if (actionu_intparse_f(*(argv + i), *key + i, 0, NULL) == -1)
{
free(*key);
*key = NULL;
*key_size = 0;
return -1;
}
}
}
else
{
/* Check that its the only argument; it should be */
if (argc != 1) return -1;
/* Easy stuff... */
columnar_transposition_text2key(ch, strtlens(*(argv), sz),
key, key_size);
if (key == NULL || key_size == 0) return -1;
}
if (columnar_transposition_verify_key(*key, *key_size) == -1)
{
printf("bad key (repeated numbers or out of range)\n");
free(*key);
*key = NULL;
*key_size = 0;
return -1;
}
return 0;
}
int actionu_ctrans_default(int argc, char **argv,
int flip, char *dirstring, char *typestring,
columnar_transposition_function routine)
{
int buffer_in, buffer_out, filter, key_size;
int *key;
if (argc < 3) return -1;
buffer_in = actionu_bufferparse_f(*(argv));
buffer_out = actionu_bufferparse_f(*(argv + 1));
if (buffer_in == -1)
{
printf(actionu_bufferparse_fail, *(argv), cfsh_num_buffers);
return -1;
}
if (buffer_out == -1)
{
printf(actionu_bufferparse_fail, *(argv + 1), cfsh_num_buffers);
return -1;
}
if (actionu_bufferchk_f(buffer_in, buffer_out) == -1) return -1;
actionu_bufferschk(buffer_in, buffer_out);
if (actionu_ctrans_keyword_parse(argc - 2, argv + 2, &key, &key_size) == -1)
return -1;
filter = get_buffer_filter(buffer_in);
if (filter == BUFFER_FILTER_NONE ||
filter == BUFFER_FILTER_ESP ||
filter == BUFFER_FILTER_ENL)
{
printf("warning: columnar transposition works on raw characters, \n"
"and so any unfiltered newlines or whitespace will be translated as well \n"
"You may want to use the filter command \n");
}
if (flip) columnar_transposition_flip_key(key, key_size);
actionu_bufferout_fn()
routine(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), key, key_size);
actionu_copysize(buffer_in, buffer_out);
printf("columnar transposition: %s using %s: \n", dirstring, typestring);
columnar_transposition_keyinfo(key, key_size);
printf("%s\n\n", get_buffer(buffer_out));
free(key);
return 0;
}
int actionu_ctrans_bruteforce(int argc, char **argv,
columnar_transposition_function routine)
{
int buffer_in, buffer_out, filter, minb, maxb;
if (argc != 4) return -1;
buffer_in = actionu_bufferparse_f(*(argv));
buffer_out = actionu_bufferparse_f(*(argv + 1));
if (buffer_in == -1)
{
printf(actionu_bufferparse_fail, *(argv), cfsh_num_buffers);
return -1;
}
if (buffer_out == -1)
{
printf(actionu_bufferparse_fail, *(argv + 1), cfsh_num_buffers);
return -1;
}
if (actionu_bufferchk_f(buffer_in, buffer_out) == -1) return -1;
actionu_bufferschk(buffer_in, buffer_out);
if (actionu_intparse_f(*(argv + 2), &minb, 0, NULL) == -1) return -1;
if (actionu_intparse_f(*(argv + 3), &maxb, 0, NULL) == -1) return -1;
if (maxb - minb < 0 || minb < 2) return -1;
filter = get_buffer_filter(buffer_in);
if (filter == BUFFER_FILTER_NONE ||
filter == BUFFER_FILTER_ESP ||
filter == BUFFER_FILTER_ENL)
{
printf("warning: columnar transposition works on raw characters, \n"
"and so any unfiltered newlines or whitespace will be translated as well \n"
"You may want to use the filter command \n");
}
actionu_bufferout_fn()
columnar_transposition_bruteforce(get_buffer(buffer_in),
get_buffer_real_size(buffer_in),
get_buffer(buffer_out),
minb, maxb, routine);
actionu_copysize(buffer_in, buffer_out);
return 0;
}
#define actionu_ctrans_auto(flip, dir, type) \
actionu_funcchk(actionu_ctrans_default(argc, argv, flip, #dir, #type, \
&(columnar_transposition_ ## type))) \
return CFSH_OK;
#define actionu_ctrans_auto_encode(type) actionu_ctrans_auto(0, encode, type)
#define actionu_ctrans_auto_decode(type) actionu_ctrans_auto(1, decode, type)
#define actionu_ctrans_bruteforce_auto(type) \
actionu_funcchk(actionu_ctrans_bruteforce(argc, argv, \
&(columnar_transposition_ ## type))) \
return CFSH_OK;
#define ACTION_USAGE action_ctrans_keyinfo_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_ctrans_keyinfo(int argc, char **argv)
{
int *key, key_size;
if (argc == 0) actionu_fail();
actionu_funcchk(actionu_ctrans_keyword_parse(argc, argv, &key, &key_size))
columnar_transposition_keyinfo(key, key_size);
columnar_transposition_flip_key(key, key_size);
printf("flipped ");
columnar_transposition_keyinfo(key, key_size);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_c2c_encode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_c2c_encode(int argc, char **argv)
{
actionu_ctrans_auto_encode(col2col)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_c2c_decode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_c2c_decode(int argc, char **argv)
{
actionu_ctrans_auto_decode(col2col)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_c2c_bruteforce_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_c2c_bruteforce(int argc, char **argv)
{
actionu_ctrans_bruteforce_auto(col2col)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_r2c_encode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_r2c_encode(int argc, char **argv)
{
actionu_ctrans_auto_encode(row2col)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_r2c_decode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_r2c_decode(int argc, char **argv)
{
actionu_ctrans_auto_decode(row2col)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_r2c_bruteforce_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_r2c_bruteforce(int argc, char **argv)
{
actionu_ctrans_bruteforce_auto(row2col)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_c2r_encode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_c2r_encode(int argc, char **argv)
{
actionu_ctrans_auto_encode(col2row)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_c2r_decode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_c2r_decode(int argc, char **argv)
{
actionu_ctrans_auto_decode(col2row)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_c2r_bruteforce_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_c2r_bruteforce(int argc, char **argv)
{
actionu_ctrans_bruteforce_auto(col2row)
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_keyb_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_keyb(int argc, char **argv)
{
int buffer_in, buffer_out;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_dictcheck()
actionu_bufferout_fn()
keyword_bruteforce(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out));
actionu_copysize(buffer_in, buffer_out);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_keye_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_keye(int argc, char **argv)
{
int buffer_in, buffer_out, key_size;
char *keyword;
actionu_argchk(3)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
keyword = *(argv + 2);
keyword += strleft(keyword);
key_size = strtlen(keyword);
actionu_funcchk(keyword_check(keyword, key_size));
actionu_bufferout_fn()
keyword_single(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), keyword, key_size, 0);
actionu_copysize(buffer_in, buffer_out);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_keyd_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_keyd(int argc, char **argv)
{
int buffer_in, buffer_out, key_size;
char *keyword;
actionu_argchk(3)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
keyword = *(argv + 2);
keyword += strleft(keyword);
key_size = strtlen(keyword);
actionu_funcchk(keyword_check(keyword, key_size));
actionu_bufferout_fn()
keyword_single(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), keyword, key_size, 1);
actionu_copysize(buffer_in, buffer_out);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_keyt_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_keyt(int argc, char **argv)
{
int key_size;
int table[26];
char *keyword;
actionu_argchk(1)
keyword = *(argv);
keyword += strleft(keyword);
key_size = strtlen(keyword);
*(keyword + key_size) = 0;
actionu_funcchk(keyword_check(keyword, key_size));
keyword_table(keyword, key_size, table);
printf("Translation table for keyword '%s': \n", keyword);
keyword_print_keyinfo(table);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_keytf_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_keytf(int argc, char **argv)
{
int key_size;
int table[26];
char *keyword;
actionu_argchk(1)
keyword = *(argv);
keyword += strleft(keyword);
key_size = strtlen(keyword);
*(keyword + key_size) = 0;
actionu_funcchk(keyword_check(keyword, key_size));
keyword_table_preflipped(keyword, key_size, table);
printf("Decode (flipped) translation table for keyword '%s': \n", keyword);
keyword_print_keyinfo(table);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_polybius_encode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_polybius_encode(int argc, char **argv)
{
int buffer_in, buffer_out;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferfchk(buffer_in, BUFFER_FILTER_ALPHA)
if (get_buffer_real_size(buffer_in) * 2 > get_buffer_size(buffer_out))
{
printf("auto expanding output buffer %i to %i bytes (just in case).\n",
buffer_out, get_buffer_real_size(buffer_in) * 2);
resizebuffer(buffer_out, get_buffer_real_size(buffer_in) * 2);
}
get_buffer_filter(buffer_out) = BUFFER_FILTER_NUM;
polybius_encode(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_polybius_decode_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_polybius_decode(int argc, char **argv)
{
int buffer_in, buffer_out;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferfchk(buffer_in, BUFFER_FILTER_NUM)
if (modp(get_buffer_real_size(buffer_in), 2) == 1)
{
printf("input buffer doesn't have an even number of characters.");
actionu_faili()
}
if ((get_buffer_real_size(buffer_in) / 2) > get_buffer_size(buffer_out))
{
printf("auto expanding output buffer %i to %i bytes (just in case).\n",
buffer_out, (get_buffer_real_size(buffer_in) / 2));
resizebuffer(buffer_out, (get_buffer_real_size(buffer_in) / 2));
}
get_buffer_filter(buffer_out) = BUFFER_FILTER_ALPHA;
polybius_decode(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_rfbf_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_rfbf(int argc, char **argv)
{
int buffer_in, buffer_out, filter, minb, maxb;
actionu_argchk(4)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_intparse(*(argv + 2), minb)
actionu_intparse(*(argv + 3), maxb)
if (minb < 2 || maxb - minb < 0) actionu_fail()
filter = get_buffer_filter(buffer_in);
if (filter == BUFFER_FILTER_NONE ||
filter == BUFFER_FILTER_ESP ||
filter == BUFFER_FILTER_ENL)
{
printf("warning: columnar transposition works on raw characters, \n"
"and so any unfiltered newlines or whitespace will be translated as well \n"
"You may want to use the filter command \n");
}
actionu_bufferout_fn()
rf_bf(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), minb, maxb);
actionu_copysize(buffer_in, buffer_out);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_vigenere_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_vigenere(int argc, char **argv)
{
int buffer_in, buffer_out, minb, maxb;
actionu_argchk(4)
actionu_bufferparse(*(argv), buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferschk(buffer_in, buffer_out);
actionu_intparse(*(argv + 2), minb)
actionu_intparse(*(argv + 3), maxb)
if (minb < 1 || maxb - minb < 0) actionu_fail()
actionu_bufferout_fn()
crack_vigenere(get_buffer(buffer_in), get_buffer_real_size(buffer_in),
get_buffer(buffer_out), minb, maxb);
actionu_copysize(buffer_in, buffer_out);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
cifer-1.2.0/src/actions_io.c 0000644 0001750 0001750 00000023035 11156502713 014030 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
#define ACTION_USAGE action_buffers_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_buffers(int argc, char **argv)
{
int num;
actionu_argchk(1)
actionu_intparse(*(argv), num)
if (num < 0) actionu_fail()
create_buffers(num);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_resize_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_resize(int argc, char **argv)
{
int newsize, buffer_id;
actionu_argchk(2)
actionu_intparse(*(argv + 1), newsize)
actionu_bufferparse(*(argv), buffer_id)
if (newsize < 1) actionu_fail()
printf("resizebuffer: resizing buffer_%i to %i bytes...\n",
buffer_id, newsize);
resizebuffer(buffer_id, newsize);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_clear_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_clear(int argc, char **argv)
{
int buffer_id;
actionu_argchk(1)
actionu_bufferparse(*(argv), buffer_id)
printf("clearbuffer: clearing buffer_%i...\n", buffer_id);
clearbuffer(buffer_id);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_copy_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_copy(int argc, char **argv)
{
int buffer_id_1, buffer_id_2;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_id_1)
actionu_bufferparse(*(argv + 1), buffer_id_2)
actionu_bufferchk(buffer_id_1, buffer_id_2)
copybuffer(buffer_id_1, buffer_id_2);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_load_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_load(int argc, char **argv)
{
int buffer_id;
actionu_argchk(2)
actionu_bufferparse(*(argv + 1), buffer_id)
file2buffer(*(argv), buffer_id);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_write_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_write(int argc, char **argv)
{
int mode, buffer_id;
if (argc != 2 && argc != 3) actionu_fail()
if (argc == 3)
{
if (strcasecmp(*(argv + 2), "auto") == 0)
{
mode = CFSH_IO_MODE_AUTO;
}
else if (strcasecmp(*(argv + 2), "overwrite") == 0)
{
mode = CFSH_IO_MODE_OVERWRITE;
}
else if (strcasecmp(*(argv + 2), "append") == 0)
{
mode = CFSH_IO_MODE_APPEND;
}
else
{
printf(action_write_usage);
return CFSH_COMMAND_HARDFAIL;
}
}
else
{
mode = CFSH_IO_MODE_AUTO;
}
actionu_bufferparse(*(argv + 1), buffer_id)
buffer2file(*(argv), buffer_id, mode);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_filter_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_filter(int argc, char **argv)
{
int mode, buffer_id;
actionu_argchk(2)
actionu_bufferparse(*(argv), buffer_id)
mode = get_buffer_filter_fromtext(*(argv + 1));
if (mode == BUFFER_FILTER_NONE)
{
printf("filter: invalid filter name\n");
actionu_faili()
}
filterbuffer(buffer_id, mode);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_read_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_read(int argc, char **argv)
{
int buffer_id;
actionu_argchk(1)
actionu_bufferparse(*(argv), buffer_id)
printf(" Buffer %i: %i/%i bytes. Filter %s. \n\n", buffer_id,
get_buffer_real_size(buffer_id), get_buffer_size(buffer_id),
get_buffer_filter_text(buffer_id));
printf("%s\n", get_buffer(buffer_id));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_bufferinfo_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_bufferinfo(int argc, char **argv)
{
int buffer_id;
actionu_argchk(1)
actionu_bufferparse(*(argv), buffer_id)
printf(" Buffer %i: %i/%i bytes. Filter %s. \n", buffer_id,
get_buffer_real_size(buffer_id), get_buffer_size(buffer_id),
get_buffer_filter_text(buffer_id));
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_nullbuffer_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_nullbuffer(int argc, char **argv)
{
int buffer_id;
actionu_argchk(1)
actionu_bufferparse(*(argv), buffer_id)
setbuffernull(buffer_id);
printf("set buffer %i's safety-null byte.\n", buffer_id);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_script_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_script(int argc, char **argv)
{
actionu_argchk(1)
cfsh_scriptfile(*argv, 0, 0);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_quickscript_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_quickscript(int argc, char **argv)
{
actionu_argchk(1)
cfsh_scriptfile(*argv, 1, 0);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_softscript_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_softscript(int argc, char **argv)
{
actionu_argchk(1)
cfsh_scriptfile(*argv, 0, 1);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_quicksoftscript_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_quicksoftscript(int argc, char **argv)
{
actionu_argchk(1)
cfsh_scriptfile(*argv, 1, 1);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_score_usage
#define ACTION_FAIL CFSH_COMMAND_SOFTFAIL
int action_score(int argc, char **argv)
{
int buffer_id, sizecache;
actionu_argchk(1)
actionu_bufferparse(*(argv), buffer_id)
sizecache = get_buffer_real_size(buffer_id);
actionu_dictcheck()
printf(" Buffer %i: %i/%i bytes. Filter %s. \n", buffer_id,
sizecache, get_buffer_size(buffer_id),
get_buffer_filter_text(buffer_id));
printf(" Dictionary Score: %i/%i \n",
score_text_dict_fast(get_buffer(buffer_id), sizecache), sizecache);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_spaces_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_spaces(int argc, char **argv)
{
int buffer_in, buffer_out, sizecache, sizeadd, i, j;
int *space_array;
char *in, *out;
actionu_argchk(2)
actionu_bufferparse(*(argv) , buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferchk(buffer_in, buffer_out)
actionu_bufferfchk(buffer_in, BUFFER_FILTER_ESP)
actionu_dictcheck()
sizecache = get_buffer_real_size(buffer_in);
sizeadd = 0;
space_array = malloc_good( sizeof(int) * sizecache );
score_text_dict_spaces(get_buffer(buffer_in), sizecache, space_array);
for (i = 0; i < sizecache; i++) if (*(space_array + i)) sizeadd++;
if (get_buffer_size(buffer_out) < (sizecache + sizeadd))
{
printf("spaces: must increase buffer size to %i bytes.\n",
sizecache + sizeadd);
resizebuffer(buffer_out, sizecache + sizeadd);
}
in = get_buffer(buffer_in);
out = get_buffer(buffer_out);
get_buffer_filter(buffer_out) = BUFFER_FILTER_ENL;
j = 0;
for (i = 0; i < sizecache; i++)
{
*(out + j) = *(in + i);
j++;
if (*(space_array + i))
{
*(out + j) = ' ';
j++;
}
}
printf("\n%s\n\n", out);
free(space_array);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_wordwrap_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_wordwrap(int argc, char **argv)
{
int buffer_in, buffer_out, sizecache, sizeadd, i, j;
int *nl_array;
char *in, *out;
actionu_argchk(2)
actionu_bufferparse(*(argv) , buffer_in)
actionu_bufferparse(*(argv + 1), buffer_out)
actionu_bufferfchk(buffer_in, BUFFER_FILTER_ENL)
actionu_bufferchk(buffer_in, buffer_out)
sizecache = get_buffer_real_size(buffer_in);
sizeadd = 0;
nl_array = malloc_good( sizeof(int) * sizecache );
cf_wordwrap(get_buffer(buffer_in), sizecache, nl_array);
for (i = 0; i < sizecache; i++) if (*(nl_array + i)) sizeadd++;
if (get_buffer_size(buffer_out) < (sizecache + sizeadd))
{
printf("wordwrap: must increase buffer size to %i bytes.\n",
sizecache + sizeadd);
resizebuffer(buffer_out, sizecache + sizeadd);
}
in = get_buffer(buffer_in);
out = get_buffer(buffer_out);
actionu_bufferout_fn()
j = 0;
for (i = 0; i < sizecache; i++)
{
*(out + j) = *(in + i);
j++;
if (*(nl_array + i))
{
*(out + j) = '\n';
j++;
}
}
printf("\n%s\n\n", out);
free(nl_array);
return CFSH_OK;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
#define ACTION_USAGE action_loaddict_usage
#define ACTION_FAIL CFSH_COMMAND_HARDFAIL
int action_loaddict(int argc, char **argv)
{
actionu_argchk(1)
load_dict(*argv);
if (dict != NULL) return CFSH_OK;
else return CFSH_COMMAND_HARDFAIL;
}
#undef ACTION_USAGE
#undef ACTION_FAIL
cifer-1.2.0/src/polybius.c 0000644 0001750 0001750 00000005455 11156502713 013555 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
int polybius_grid_25_int[26] = { 11, 12, 13, 14, 15,
21, 22, 23, 24, 24, 25,
31, 32, 33, 34, 35,
41, 42, 43, 44, 45,
51, 52, 53, 54, 55 };
void polybius_encode(char *intext, int intext_size, char *outtext)
{
int i, j, ch, pch, d1, d2;
for (i = 0, j = 0; i < intext_size; i++, j += 2)
{
/* Grab the charnum and check its alpha ok */
ch = CHARNUM(*(intext+ i));
if (ch == -1)
{
*(outtext) = 0;
return;
}
/* Convert to a polybius number */
pch = polybius_grid_25_int[ch];
/* Work out the digits */
d2 = modp(pch, 10);
d1 = (pch - d2) / 10;
/* Convert to ascii and save */
*(outtext + j) = NUMNUMCHAR(d1);
*(outtext + j + 1) = NUMNUMCHAR(d2);
}
/* Null Termination */
*(outtext + j) = 0;
/* Results */
printf("Polybius Encrypt:\n\n");
printf("%s\n\n", outtext);
}
void polybius_decode(char *intext, int intext_size, char *outtext)
{
int i, n, h, ptext_done;
char ch1, ch2;
/* Prepare */
ptext_done = 0;
*(outtext) = 0;
/* Must be an even number of characters: action_ should check this */
if (modp(intext_size, 2) != 0) return;
/* Start looping! Take characters two at a time */
for (i = 0; i < intext_size; i += 2)
{
ch1 = *(intext + i);
ch2 = *(intext + i + 1);
if (!NUMBER_CH(ch1) || !NUMBER_CH(ch2))
{
*(outtext) = 0; /* Null the first char, effectivly empties it */
return;
}
n = (NUMCHARNUM(ch1) * 10) + NUMCHARNUM(ch2);
for (h = 0; h < 26; h++)
{
if (polybius_grid_25_int[h] == n)
{
/* Match */
*(outtext + ptext_done) = NUMCHAR(h);
ptext_done++;
break;
}
}
/* It got to the end!!! Match fail */
if (h == 26)
{
*(outtext) = 0;
return;
}
}
/* Null termination */
*(outtext + ptext_done) = 0;
/* Results */
printf("Polybius Decrypt:\n\n");
printf("%s\n\n", outtext);
}
cifer-1.2.0/src/shell.c 0000644 0001750 0001750 00000023256 11156502713 013015 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
char *cfsh_commandline;
char *rl_gets()
{
/* Clean up an old line */
if (cfsh_commandline)
{
free(cfsh_commandline);
cfsh_commandline = NULL;
}
/* Get a line from the user. */
cfsh_commandline = readline("cifer> ");
return cfsh_commandline;
}
void cfsh_init()
{
/* Crucial startup routines. Basically initialises global variables. */
buffers_init();
init_dict();
cifer_header();
/* Simple nulling */
cfsh_commandline = NULL;
}
void cifer_header()
{
printf(" --- Cifer " VERSION " --- \n");
printf("Copyright 2008 Simrun Basuita & Daniel Richman\n");
printf("License GPLv3+: GNU GPL version 3 or later "
"\n");
printf("This is free software: you are free to change "
"and redistribute it.\n");
printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
printf("Compiled with: Cipher cracking lanuage: " DESIGNLANG "\n");
printf(" Optimal Delta IC : %f\n", OPTIMAL_DELTA_IC);
printf(" Dictionary max wordlen: %i\n", WORD_BUF_SIZE);
printf(" Dictionary min wordlen: %i\n\n", MIN_WORD_SIZE);
}
void cfsh_autoinit()
{
/* Automatic "we guessed you wanted this" stuff:
* Make 10 Buffers */
create_buffers(10);
printf("\n");
}
int cfsh_read(FILE *read, int mode)
{
/* Enter the Loop, accepting stuff from read and passing to cfsh_line */
int result, looping, linesize, i, num, have_nl, szc, rl_null_ended;
char *line;
/* To please -O2, we initialise it to NULL. It should never be
* used uninitialised afaik, however, the testing of `mode` which is
* done twice is treaded by -O2 as not-neccacarily the same, and so it
* flags up uninitialised use. With NULL its a nice clean segfault should
* anything go whacky */
line = NULL;
if (mode != CFSH_READ_MODE_INTERACTIVE)
{
/* Start out at 512 chars */
line = malloc_good( 512 );
linesize = 512;
}
/* Gogogo! */
looping = 1;
num = 0;
rl_null_ended = 0;
result = CFSH_OK;
/* Shouldn't happen */
if (mode == CFSH_READ_MODE_INTERACTIVE && read != stdin)
{
return CFSH_OK;
}
while (looping && feof(read) == 0 && rl_null_ended != 1)
{
if (mode != CFSH_READ_MODE_INTERACTIVE)
{
*line = 0; /* Set the first byte so */
have_nl = 0;
for (i = 0; feof(read) == 0 && !have_nl; i++)
{
if (i >= linesize - 1)
{
line = realloc_good( line, linesize + 512 );
linesize += 512;
}
*(line + i) = fgetc(read);
if (IS_NEWLINE(*(line + i)) || *(line + i) == -1)
{
*(line + i) = 0;
have_nl = 1;
}
}
}
else
{
line = rl_gets();
/* If a EOF was fired in interactive mode, an extra \n is
* needed for niceness */
if (line == NULL)
{
rl_null_ended = 1;
printf("\n");
}
}
/* If it is > than 0 length and its not a #comment... */
/* To ensure we can test the first char, we do this */
if (line == NULL) szc = 0;
else szc = strlen(line);
/* This relies on && not bothering with the next tests if
* a previous one is false, as is the default behaviour
* This tests if the line is not null, has some chars in it,
* and isn't a #comment */
if (line != NULL && strtlens(line, szc) != 0 &&
*(line + strlefts(line, szc)) != '#')
{
/* If its not from stdin, then echo it out */
if (mode != CFSH_READ_MODE_INTERACTIVE &&
mode != CFSH_READ_MODE_PARSECHECK)
printf("cifer> %s\n", line);
/* If its from stdin, lets add it to the history */
if (mode == CFSH_READ_MODE_INTERACTIVE)
add_history(line);
if (mode != CFSH_READ_MODE_INTERACTIVE)
{
/* Pop it into here, an untainted copy */
cfsh_commandline = realloc_good(cfsh_commandline, szc + 1);
memcpy(cfsh_commandline, line, szc);
*(cfsh_commandline + szc) = 0;
}
/* Execute/parse and update loop status from mode */
switch (mode)
{
case CFSH_READ_MODE_PARSECHECK:
result = cfsh_line(line, mode);
if (result == CFSH_COMMAND_PARSEFAIL)
{
printf("cfsh_read: parse reports error on line %i.\n", num);
looping = 0;
}
break;
case CFSH_READ_MODE_EXECUTE_SF:
result = cfsh_line(line, mode);
if (result == CFSH_COMMAND_HARDFAIL ||
result == CFSH_COMMAND_SOFTFAIL ||
result == CFSH_COMMAND_PARSEFAIL)
{
printf("cfsh_read: exit requested by cfsh_line on softhard err.\n");
looping = 0;
}
break;
case CFSH_READ_MODE_EXECUTE_HF:
result = cfsh_line(line, mode);
if (result == CFSH_COMMAND_HARDFAIL)
{
printf("cfsh_read: exit requested by cfsh_line on hard err.\n");
looping = 0;
}
break;
case CFSH_READ_MODE_INTERACTIVE:
result = cfsh_line(line, mode);
break;
}
if (result == CFSH_BREAK_LOOP)
{
printf("cfsh_read: break_loop requested (graceful)\n");
looping = 0;
}
num++;
}
}
if (mode != CFSH_READ_MODE_PARSECHECK || result == CFSH_COMMAND_PARSEFAIL)
printf("cfsh_read: read %i lines.\n", num);
if ((mode != CFSH_READ_MODE_PARSECHECK || result == CFSH_COMMAND_PARSEFAIL) &&
feof(read) != 0) printf("cfsh_read: end of file\n");
if (!looping) printf("cfsh_read: loop broken by cfsh_line\n");
if (mode != CFSH_READ_MODE_INTERACTIVE && line != NULL) free(line);
/* For Parsecheck, the last result will either
* be the error or all are ok. Otherwise, this means that
* the last instruction is the exit code.*/
return result;
}
void cfsh_scriptfile(char *name, int preparse, int softfail)
{
/* Execute the file, taking each line and giving it to cfsh_line */
FILE *read;
int result;
read = fopen(name, "r");
if (read == NULL)
{
printf("cfsh_scriptfile: failed to open %s: %s\n", name, strerror(errno));
return;
}
flock(fileno(read), LOCK_SH);
if (preparse)
{
result = cfsh_read(read, CFSH_READ_MODE_PARSECHECK);
if (result == CFSH_COMMAND_PARSEFAIL)
printf("cfsh_scriptfile: parse error in file, not executing.\n");
rewind(read);
}
else
{
result = CFSH_OK;
}
if (result == CFSH_OK)
{
if (softfail) result = cfsh_read(read, CFSH_READ_MODE_EXECUTE_SF);
else result = cfsh_read(read, CFSH_READ_MODE_EXECUTE_HF);
}
flock(fileno(read), LOCK_UN);
fclose(read);
}
int cfsh_line(char *input, int mode)
{
/* Use command.c to parse it, execute it and free it. command.c functions
* won't produce output or errors to stdout, so you must do that here. */
cfsh_execinfo execinfo;
struct timeval time1, time2;
int result;
result = cfsh_parse(input, &execinfo);
/* No need to break, we has return
* Also, there's no need for free_execinfo because if we
* parsefail, nothing should have been allocated. */
switch (result)
{
case CFSH_PARSE_EBAD:
if (mode == CFSH_READ_MODE_PARSECHECK) printf("\ncifer> %s\n", input);
printf("cfsh_parse: escape sequence misuse\n");
if (mode != CFSH_READ_MODE_PARSECHECK) printf("\n");
return CFSH_COMMAND_PARSEFAIL;
case CFSH_PARSE_EMPTY:
if (mode == CFSH_READ_MODE_PARSECHECK) printf("\ncifer> %s\n", input);
printf("cfsh_parse: no command specified\n");
if (mode != CFSH_READ_MODE_PARSECHECK) printf("\n");
return CFSH_COMMAND_PARSEFAIL;
case CFSH_PARSE_QUOTEOPEN:
if (mode == CFSH_READ_MODE_PARSECHECK) printf("\ncifer> %s\n", input);
printf("cfsh_parse: quotes left open/unclosed.\n");
if (mode != CFSH_READ_MODE_PARSECHECK) printf("\n");
return CFSH_COMMAND_PARSEFAIL;
case CFSH_FUNC_NOEXIST:
if (mode == CFSH_READ_MODE_PARSECHECK) printf("\ncifer> %s\n", input);
printf("cfsh_parse: no such command or function\n");
if (mode != CFSH_READ_MODE_PARSECHECK) printf("\n");
return CFSH_COMMAND_PARSEFAIL;
}
if (mode == CFSH_READ_MODE_PARSECHECK) return CFSH_OK;
/* gettimeofday should never fail */
gettimeofday(&time1, NULL);
result = cfsh_exec(execinfo);
gettimeofday(&time2, NULL);
/* Free up */
cfsh_free_execinfo(&execinfo);
/* timing info. note: microsecond = one millionth */
/* Subtract time1 from time2 */
time2.tv_sec -= time1.tv_sec;
time2.tv_usec -= time1.tv_usec;
/* Fix any overlap/carry-over */
if (time2.tv_usec < 0)
{
time2.tv_sec--;
time2.tv_usec += 1000000;
}
/* Only print if its significant */
if (time2.tv_sec > 0)
{
printf("\n");
printf("cfsh_line: command spent %6li.%.6li seconds.\n",
time2.tv_sec, time2.tv_usec);
/* Use printf to provide 000s on the left of usec, to make it correct ;) */
}
/* nice spacing =) */
printf("\n");
return result;
}
cifer-1.2.0/src/affine.h 0000644 0001750 0001750 00000002126 11156502713 013134 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
int affine_solve(int cl_1, int pl_1, int cl_2, int pl_2, int *a, int *b);
void crack_affine(char *intext, int intext_size, char *outtext);
void affine_bf(char *intext, int intext_size, char *outtext);
void affine_encode(char *intext, int intext_size, char *outtext, int a, int b);
void affine_decode(char *intext, int intext_size, char *outtext, int a, int b);
cifer-1.2.0/src/actions_macros.h 0000644 0001750 0001750 00000006515 11156502713 014716 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#define actionu_faili() printf(ACTION_USAGE); return ACTION_FAIL;
#define actionu_fail() { actionu_faili() }
#define actionu_failchk(x) if (!(x)) actionu_fail()
#define actionu_funcchk(x) if ((x) == -1) actionu_fail()
#define actionu_argchk(i) actionu_failchk(argc == (i))
#define actionu_argless() actionu_argchk(0)
#define actionu_intparse(s, t) \
actionu_funcchk(actionu_intparse_f((s), &(t), 0, NULL))
#define actionu_intparse_char(s, t) \
actionu_funcchk(actionu_intparse_f((s), &(t), 1, NULL))
#define actionu_intparsef(s, t, f) \
actionu_funcchk(actionu_intparse_f((s), &(t), 0, (f)))
#define actionu_intparsef_char(s, t, f) \
actionu_funcchk(actionu_intparse_f((s), &(t), 1, (f)))
#define actionu_bufferparse(s, t) \
{ \
t = actionu_bufferparse_f((s)); \
\
if (t == -1) \
{ \
if (cfsh_num_buffers == 0) \
printf(actionu_bufferparse_zerofail, (s)); \
else \
printf(actionu_bufferparse_fail, (s), cfsh_num_buffers - 1); \
\
actionu_faili() \
} \
}
#define actionu_bufferchk(i, o) actionu_funcchk(actionu_bufferchk_f((i), (o)))
#define actionu_bufferfchk(b, f) actionu_funcchk(actionu_bufferfchk_f((b), (f)))
#define actionu_buffer_fn(b) get_buffer_filter(b) = BUFFER_FILTER_NONE;
#define actionu_bufferout_fn() actionu_buffer_fn(buffer_out)
#define actionu_dictcheck() \
if (dict == NULL) \
{ \
printf("dictionary not loaded. use `loaddict`\n"); \
actionu_faili() \
}
cifer-1.2.0/src/vigenere.h 0000644 0001750 0001750 00000001654 11156502713 013515 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
typedef struct {
int column_size;
double column_ic_diff;
} vigenere_column_ic;
void crack_vigenere(char *intext, int intext_size, char *outtext,
int minb, int maxb);
cifer-1.2.0/src/actions_head.c 0000644 0001750 0001750 00000005471 11156502713 014326 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
int actionu_intparse_f(char *str, int *value, int char_mode, void *failfree)
{
size_t sz;
char *validator, *target;
sz = strlen(str);
if (char_mode && strtlens(str, sz) == 1 &&
ALPHA_CH( *(str + strlefts(str, sz)) ))
{
*value = CHARNUM( *(str + strlefts(str, sz)) );
return 0;
}
target = str + sz - strrights(str, sz);
*value = strtol(str + strlefts(str, sz), &validator, 10);
if (validator != target)
{
if (failfree != NULL) free(failfree);
return -1;
}
return 0;
}
int actionu_bufferparse_f(char *str)
{
/* strlen("buffer_") = 7 */
size_t sz;
long j;
char *validator;
sz = strlen(str);
if (strtlens(str, sz) < 8) return -1;
if (strncasecmp(str, "buffer_", 7) != 0) return -1;
j = strtol(str + strlefts(str, sz) + 7, &validator, 10);
if (validator != (str + sz - strrights(str, sz))) return -1;
if (j >= cfsh_num_buffers) return -1;
if (j < 0) return -1;
return j;
}
int actionu_bufferchk_f(int buffer_in, int buffer_out)
{
if (get_buffer_real_size(buffer_in) == 0)
{
printf("bad input buffer: no data.\n");
return -1;
}
if (buffer_in == buffer_out)
{
printf("bad output buffer: same as input buffer.\n");
return -1;
}
return 0;
}
int actionu_bufferfchk_f(int buffer_id, int filter)
{
if (get_buffer_filter(buffer_id) != filter)
{
printf("bad input buffer: filter type '%s' should be '%s'. \n",
get_buffer_filter_text(buffer_id), get_filter_text(filter) );
return -1;
}
return 0;
}
void actionu_bufferschk(int buffer_in, int buffer_out)
{
if (get_buffer_real_size(buffer_in) > get_buffer_size(buffer_out))
{
printf("auto expanding output buffer_%i to %i bytes.\n", buffer_out,
get_buffer_real_size(buffer_in));
resizebuffer(buffer_out, get_buffer_real_size(buffer_in));
}
}
void actionu_copysize(int buffer_in, int buffer_out)
{
*(get_buffer(buffer_out) + get_buffer_real_size(buffer_in)) = 0;
setbuffernull(buffer_out);
}
cifer-1.2.0/src/bacon.c 0000644 0001750 0001750 00000005511 11156502713 012762 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
#include "stdinc.h"
char *bacon_alphabet[26] = { "AAAAA", "AAAAB", "AAABA", "AAABB",
"AABAA", "AABAB", "AABBA", "AABBB",
"ABAAA", "ABAAA", "ABAAB", "ABABA",
"ABABB", "ABBAA", "ABBAB", "ABBBA",
"ABBBB", "BAAAA", "BAAAB", "BAABA",
"BAABB", "BAABB", "BABAA", "BABAB",
"BABBA", "BABBB" };
void bacon_encode(char *intext, int intext_size, char *outtext)
{
int i, j;
char ch;
printf("Encrypting using bacon cipher...\n");
for (i = 0, j = 0; i < intext_size; i++)
{
ch = *(intext + i);
if (ALPHA_CH(ch))
{
memcpy(outtext + j, bacon_alphabet[CHARNUM(ch)], 5);
j += 5;
}
else
{
*(outtext + j) = ch;
j++;
}
}
*(outtext + j) = 0;
printf("\n%s\n\n", outtext);
}
void bacon_decode(char *intext, int intext_size, char *outtext)
{
int i, j, h, ptext_done; /* Counters */
char buf[5], ch;
/* Prepare */
j = 0; /* Number of chars written into buf */
ptext_done = 0; /* Number of ptext chars written */
/* Header & stats */
printf("Decoding bacon cipher... \n");
for (i = 0; i < intext_size; i++)
{
ch = *(intext + i);
if (CHARNUM(ch) == 0 || CHARNUM(ch) == 1)
{
buf[j] = ch;
j++;
}
/* We have one block filled, check it out */
if (j == 5)
{
/* Check against each letter in the alphabet */
for (h = 0; h < 26; h++)
{
if ((strncmp(buf, bacon_alphabet[h], 5)) == 0)
{
/* We have a match! Don't worry about overlapping, we've
* buffered it so it should be fine */
*(outtext + ptext_done) = NUMCHAR(h);
ptext_done++;
break;
}
}
if (h == 26)
{
printf("Error: Invalid bacon '%s'\n", buf);
return;
}
/* Reset the counter */
j = 0;
}
}
/* Update the null terminator and the size */
*(outtext + ptext_done) = 0;
printf("\n%s\n\n", outtext);
}
cifer-1.2.0/src/columnar_transposition.c 0000644 0001750 0001750 00000022404 11156502713 016514 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
/* TODO: Look at r2c c2r reoordering is happening on rows not columns */
#include "stdinc.h"
/* KEY FORMAT: int array of size "key size", no recurring numbers
* to use, the columns are shifted. ZEBRAS: 521304. The key allways
* encodes; to decode you have to flip the key first =) (there's a
* function below to do that). The key must be starting at 0. */
void columnar_transposition_bruteforce(char *intext, int intext_size,
char *outtext, int key_min, int key_max,
columnar_transposition_function routine)
{
int key_size, i, j, k, h, factorial, np, npi, score, best_score, best_size;
int temp_text_size;
int *key, *key_best;
score_text_pro_state pro_state;
/* Allocate to the maximum size, that's means we only have to alloc once */
key = malloc_good(sizeof(int) * key_max);
key_best = malloc_good(sizeof(int) * key_max);
/* Clip the size of the temporary text to make it quicker */
temp_text_size = min(600, intext_size);
/* We'll use the outtext as temporary space as well, so lets shove a
* null in the right place to be sure */
*(outtext + temp_text_size) = 0;
/* Prepare */
best_score = -1;
best_size = 0;
/* Go Pro! */
score_text_pro_start(temp_text_size, &pro_state);
/* Print a header */
printf("Columnar Transposition Bruteforce: %i => %i, using %i chars\n",
key_min, key_max, temp_text_size);
printf(" -> key_size - factorial | loops/bar: progress...\n");
/* Start teh cracking! */
for (key_size = key_min; key_size <= key_max; key_size++)
{
/* Calcualte the factorial */
factorial = 1;
for (i = 2; i <= key_size; i++) factorial *= i;
/* Sub-progress indicator setup */
npi = max(factorial / 30, 1); /* How many loops equals a new bar? */
np = npi; /* The running "next loop for bar" precache */
/* Progress indicator */
printf(" -> %3i - %8i | %7i: ", key_size, factorial, npi);
fflush(stdout);
for (i = 1; i <= factorial; i++)
{
/* Initialise the key */
for (j = 0; j < key_size; j++) key[j] = j;
/* Prepare */
k = i;
/* Generate the permutation */
for (j = 2; j <= key_size; j++)
{
k = k / (j - 1);
h = key[modp(k, j)];
key[modp(k, j)] = key[j - 1];
key[j - 1] = h;
}
/* Try it */
(*routine)(intext, temp_text_size, outtext, key, key_size);
/* Score it */
score = score_text_pro(outtext, &pro_state);
if (score > best_score)
{
best_score = score;
best_size = key_size;
for (j = 0; j < key_size; j++) key_best[j] = key[j];
}
/* Subprocess Indicator */
if (i == np)
{
np += npi;
printf("|");
fflush(stdout);
}
}
printf("\n -> %3i - %8i: best score %4i, from length %i; key: ",
key_size, factorial, best_score, best_size);
printf("%i", key_best[0]);
for (i = 1; i < best_size; i++) printf("|%i", key_best[i]);
printf("\n");
}
/* Print _pro stats */
score_text_pro_print_stats("columnar-transposition", &pro_state);
/* Do it for real and save the result (doing for real WITH numbers) */
(*routine)(intext, intext_size, outtext, key_best, best_size);
/* Be sure about null pointers */
*(outtext + intext_size) = 0;
*(intext + intext_size) = 0;
/* Results */
printf("Columnar Transposition Bruteforce: best_score %i; key size %i\n",
best_score, best_size);
columnar_transposition_keyinfo(key_best, best_size);
printf("%s\n\n", outtext);
/* Free up */
free(key);
free(key_best);
score_text_pro_cleanup(&pro_state);
}
void columnar_transposition_keyinfo(int *key, int key_size)
{
int i;
printf("key[%i]: %i", key_size, key[0]);
for (i = 1; i < key_size; i++) printf(" %i", key[i]);
printf("\n");
}
/* Reads off into columns KEY_SIZE, reorders as per key, reads off
* in columns - the key is array[source] => target */
/* THE INPUT TEXT AND THE OUTPUT TEXT MUST BE SEPARATE STRINGS */
void columnar_transposition_col2col(char *intext, int text_size,
char *outtext, int *key, int key_size)
{
int i, chunk_start, key_item, target;
chunk_start = 0;
for (i = 0; i < text_size; i++)
{
key_item = modp(i, key_size);
if (key_item == 0) chunk_start = i;
if (chunk_start + key_size >= text_size) break;
target = chunk_start + key[key_item];
*(outtext + target) = *(intext + i);
}
/* Any remainter should just be copied from a => b */
while (i < text_size)
{
*(outtext + i) = *(intext + i);
i++;
}
}
/* Essentially writes out the text in cols (top to bottom then
* reads off in rows (left to right). This is a DECODER,
* however it requires a flipped key. */
void columnar_transposition_col2row(char *intext, int text_size,
char *outtext, int *key, int key_size)
{
int i, col_start, col_end, col_num, col_std_length, cols_incomplete, target;
col_start = 0; col_end = 0; col_num = -1;
cols_incomplete = modp(text_size, key_size);
col_std_length = (text_size - cols_incomplete) / key_size;
for (i = 0; i < text_size; i++)
{
if (i == col_end)
{
/* New col calculation is needed */
col_num++;
col_start = i;
col_end = i + col_std_length + (key[col_num] < cols_incomplete ? 1 : 0);
}
target = key[col_num] + ((i - col_start) * key_size);
*(outtext + target) = *(intext + i);
}
}
/* encodes, writes out in rows (l => r) and reads off in columns. */
void columnar_transposition_row2col(char *intext, int text_size,
char *outtext, int *key, int key_size)
{
int i, cols_incomplete, col_std_length, col_num, col_start, col_pos;
cols_incomplete = modp(text_size, key_size);
col_std_length = (text_size - cols_incomplete) / key_size;
for (col_num = 0; col_num < key_size; col_num++)
{
col_start = col_std_length * key[col_num];
col_pos = 0;
for (i = 0; i < key_size; i++)
if (i < cols_incomplete && key[i] < key[col_num]) col_start++;
for (i = col_num; i < text_size; i += key_size, col_pos++)
{
/* Source = i, target = col_start + col_pos */
*(outtext + col_start + col_pos) = *(intext + i);
}
}
}
void columnar_transposition_flip_key(int *key, int key_size)
{
int i, *temp; /* Dynamic size */
temp = malloc_good( sizeof(int) * key_size );
/* copy into temp, then flip */
for (i = 0; i < key_size; i++) temp[i] = key[i];
for (i = 0; i < key_size; i++) key[temp[i]] = i;
/* Free up */
free(temp);
}
void columnar_transposition_text2key(char *text, int text_size,
int **key, int *new_key_size)
{
int i, j, c;
int used[26];
/* Used variable cries out for initialisation */
for (i = 0; i < 26; i++) used[i] = -1;
/* Pass 1, count letters (into variable j) */
for (i = 0, j = 0; i < text_size; i++)
{
c = CHARNUM( *(text + i) );
if (c == -1)
{
/* Fail */
*key = NULL;
*new_key_size = 0;
return;
}
if (used[c] == -1)
{
used[c] = j;
j++;
}
}
/* Now allocate */
*key = malloc_good( sizeof(int) * j );
*new_key_size = j;
#define targkey (*key)
/* Pass 2: Using the used array, we can work out each items
* position in the alphabet relative to this key... */
for (i = 0, j = 0; i < 26; i++)
{
if (used[i] != -1)
{
/* because we're now going through by used[i] insted of text[i] we're
* going in alphabetical order.
* used[i] contains a reference to the character in which it occured.
* We want to filter unused characters
* And so J goes up each time we get a match, so the first alphabetic
* character order has 0.
* And we used the reference in used[i] to just save it into the key! */
targkey[used[i]] = j;
j++;
/* Hope that makes sense */
}
}
}
int columnar_transposition_verify_key(int *key, int key_size)
{
int i, *used;
/* First checks */
if (key_size < 2) return -1;
/* Allocate */
used = malloc_good( sizeof(int) * key_size );
/* Initialise */
for (i = 0; i < key_size; i++) used[i] = 0;
/* For each key value, check that it fits and then
* increment the value's use count */
for (i = 0; i < key_size; i++)
if (key[i] >= 0 && key[i] < key_size)
used[key[i]]++;
/* For anything that hasn't been used once,
* only once (ie. not too much, not too little) fail */
for (i = 0; i < key_size; i++) if (used[i] != 1) return -1;
/* Otherwise success */
return 0;
}
cifer-1.2.0/src/columnar_transposition.h 0000644 0001750 0001750 00000003366 11156502713 016527 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
typedef void(*columnar_transposition_function)(char *intext, int text_size,
char *outtext, int *key, int key_size);
void columnar_transposition_col2col(char *intext, int text_size,
char *outtext, int *key, int key_size);
void columnar_transposition_col2row(char *intext, int text_size,
char *outtext, int *key, int key_size);
void columnar_transposition_row2col(char *intext, int text_size,
char *outtext, int *key, int key_size);
void columnar_transposition_bruteforce(char *intext, int intext_size,
char *outtext, int key_min, int key_max,
columnar_transposition_function routine);
void columnar_transposition_flip_key(int *key, int key_size);
void columnar_transposition_keyinfo(int *key, int key_size);
void columnar_transposition_text2key(char *text, int text_size,
int **key, int *new_key_size);
int columnar_transposition_verify_key(int *key, int key_size);
cifer-1.2.0/src/ciphers.h 0000644 0001750 0001750 00000002223 11156502713 013337 0 ustar ssb ssb /*
Cifer: Automating classical cipher cracking in C
Copyright (C) 2008 Daniel Richman & Simrun Basuita
Cifer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Cifer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cifer. If not, see .
*/
void caesar_cipher_enc(char *intext, int intext_size, char *outtext,
int *shift, int shift_size);
void caesar_cipher_dec(char *intext, int intext_size, char *outtext,
int *shift, int shift_size);
void monoalph_substitute(char *intext, int intext_size, char *outtext,
int *translation);