/*
**** Tabuk University ****
* College Of Computer And Information Technology
* Prepaired By:
* Fahd Dayim Alanzi
* Omar Ibrahim Almayhubi
* Ibrahim Salah Alanzi
* Nasser Awad Alqadi
* Khalid Abdul Karim Alanzi
* Ali Abdullah alBelawi
**** Under supervision****
* * Dr. Ibrahim Alssadi * *
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define WIDTH 26
int gcd( int a, int b) ;
char shift( int * key, char ch) ;
char unshift( int * key, char ch) ;
int modInverse( int a, int m) ;
char * encrypt( int * key, char * src, char * dest)
{
char * pSrc = src;
char * pDest = dest;
if ( gcd( key[ 0 ] , WIDTH) ! = 1 )
{
printf ( "Error: a 与 m 不互素" ) ;
exit ( - 1 ) ;
}
for ( int i = 0 ; * pSrc; ++ i, ++ pSrc, ++ pDest)
{
if ( ! isalpha ( * pSrc) )
continue ;
* pDest = shift( key, toupper ( * pSrc) ) ;
}
return dest;
}
/*
* 解密
*
* @param key 密钥 { a, b }
* @param src 待解密的字符串
* @param dest 经过解密后的字符串
*/
char * decrypt( int * key, char * src, char * dest)
{
char * pSrc = src;
char * pDest = dest;
int arr[ 2 ] = { modInverse( key[ 0 ] , WIDTH) , - key[ 1 ] } ;
for ( int i = 0 ; * pSrc; ++ i, ++ pSrc, ++ pDest)
{
if ( ! isalpha ( * pSrc) )
continue ;
* pDest = unshift( arr, toupper ( * pSrc) ) ;
}
return dest;
}
int main( int argc, char const * argv[ ] )
{
// 本例推算见 http://e...content-available-to-author-only...a.org/wiki/Affine_cipher
int key[ ] = { 5 , 8 } ; // 密匙
char text[ ] = "AFFINECIPHER" ; // 明文
char ciphertext[ 1024 ] , result[ 1024 ] ;
// 加密
encrypt( key, text, ciphertext) ;
printf ( "%s\n " , ciphertext) ;
// 解密
decrypt( key, ciphertext, result) ;
printf ( "%s\n " , result) ;
printf ( " \n **** Tabuk University **** \n \n * College Of Computer And Information Technology * \n " "\n * Prepaired By: \n " "\n * Fahd Dayim Alanzi \n " "\n * Omar Ibrahim Almayhubi \n " "\n * Ibrahim Salah Alanzi \n " "\n * Nasser Awad Alqadi \n " "\n * Khalid Abdul Karim Alanzi \n " "\n * Ali Abdullah alBelawi \n " "\n ******* Under supervision *******\n " "\n **** Dr. Ibrahim Alssadi ****\n " ) ;
return 0 ;
}
/*
* E(x) = (ax + b) mod m
*/
char shift( int * key, char ch)
{
int offset = ch - 'A' ;
return ( key[ 0 ] * offset + key[ 1 ] ) % WIDTH + 'A' ;
}
/*
* D(x) = a^{-1}(x - b) mod m
*/
char unshift( int * key, char ch)
{
int offset = ch - 'A' ;
return ( ( ( key[ 0 ] * ( offset + key[ 1 ] ) ) % WIDTH + WIDTH) % WIDTH) + 'A' ;
}
/*
* 判断 a 与 b 是否互素
*/
int gcd( int a, int b)
{
int tmp;
while ( a ! = 0 )
{
tmp = a;
a = b % a;
b = tmp;
}
return b;
}
/*
* 求 a 在密表中的乘法逆
*/
int modInverse( int a, int m)
{
int x1, x2, x3, y1, y2, y3, t1, t2, t3, q;
x1 = y2 = 1 , x2 = y1 = 0 ;
x3 = ( a >= m ) ? a : m;
y3 = ( a >= m ) ? m : a;
while ( 1 )
{
if ( y3 == 0 )
{
return x3;
}
else if ( y3 == 1 )
{
return y2;
}
q = x3 / y3;
t1 = x1 - q * y1, t2 = x2 - q * y2, t3 = x3 - q * y3;
x1 = y1, x2 = y2, x3 = y3;
y1 = t1, y2 = t2, y3 = t3;
}
}
LyoKICAqKioqIFRhYnVrIFVuaXZlcnNpdHkgICoqKioKICogQ29sbGVnZSBPZiBDb21wdXRlciBBbmQgSW5mb3JtYXRpb24gVGVjaG5vbG9neQogKiBQcmVwYWlyZWQgQnk6IAogKiBGYWhkIERheWltIEFsYW56aQogKiBPbWFyIElicmFoaW0gQWxtYXlodWJpCiAqIElicmFoaW0gU2FsYWggQWxhbnppCiAqIE5hc3NlciBBd2FkICBBbHFhZGkKICogS2hhbGlkIEFiZHVsIEthcmltIEFsYW56aQogKiBBbGkgQWJkdWxsYWggYWxCZWxhd2kKICoqKiogVW5kZXIgc3VwZXJ2aXNpb24qKioqCiogKiBEci4gSWJyYWhpbSBBbHNzYWRpICogKiAKIAogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgoKI2RlZmluZSBXSURUSCAyNgoKaW50ICBnY2QoaW50IGEsIGludCBiKTsKY2hhciBzaGlmdChpbnQgKmtleSwgY2hhciBjaCk7CmNoYXIgdW5zaGlmdChpbnQgKmtleSwgY2hhciBjaCk7CmludCAgbW9kSW52ZXJzZShpbnQgYSwgaW50IG0pOwoKCmNoYXIgKiBlbmNyeXB0KGludCoga2V5LCBjaGFyKiBzcmMsIGNoYXIqIGRlc3QpCnsKICAgIGNoYXIgKnBTcmMgID0gc3JjOwogICAgY2hhciAqcERlc3QgPSBkZXN0OwoKICAgIGlmIChnY2Qoa2V5WzBdLCBXSURUSCkgIT0gMSkKICAgIHsKICAgICAgICBwcmludGYoIkVycm9yOiBhIOS4jiBtIOS4jeS6kue0oCIpOwogICAgICAgIGV4aXQoLTEpOwogICAgfQoKICAgIGZvciAoaW50IGkgPSAwOyAqcFNyYzsgKytpLCArK3BTcmMsICsrcERlc3QpCiAgICB7CiAgICAgICAgaWYgKCFpc2FscGhhKCpwU3JjKSkKICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICpwRGVzdCA9IHNoaWZ0KGtleSwgdG91cHBlcigqcFNyYykpOwogICAgfQoKICAgIHJldHVybiBkZXN0Owp9CgovKgogKiDop6Plr4YKICoKICogQHBhcmFtIGtleSAgICDlr4bpkqUgeyBhLCBiIH0KICogQHBhcmFtIHNyYyAgICDlvoXop6Plr4bnmoTlrZfnrKbkuLIKICogQHBhcmFtIGRlc3QgICDnu4/ov4fop6Plr4blkI7nmoTlrZfnrKbkuLIKICovCmNoYXIgKiBkZWNyeXB0KGludCoga2V5LCBjaGFyKiBzcmMsIGNoYXIqIGRlc3QpCnsKICAgIGNoYXIgKnBTcmMgID0gc3JjOwogICAgY2hhciAqcERlc3QgPSBkZXN0OwogICAgaW50ICBhcnJbMl0gPSB7IG1vZEludmVyc2Uoa2V5WzBdLCBXSURUSCksIC1rZXlbMV0gfTsKCiAgICBmb3IgKGludCBpID0gMDsgKnBTcmM7ICsraSwgKytwU3JjLCArK3BEZXN0KQogICAgewogICAgICAgIGlmICghaXNhbHBoYSgqcFNyYykpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAqcERlc3QgPSB1bnNoaWZ0KGFyciwgdG91cHBlcigqcFNyYykpOwogICAgfQoKICAgIHJldHVybiBkZXN0Owp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciBjb25zdCAqYXJndltdKQp7CiAgICAvLyDmnKzkvovmjqjnrpfop4EgaHR0cDovL2UuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLmEub3JnL3dpa2kvQWZmaW5lX2NpcGhlcgoKICAgIGludCAga2V5W10gID0geyA1LCA4IH07ICAgICAgIC8vIOWvhuWMmQogICAgY2hhciB0ZXh0W10gPSAiQUZGSU5FQ0lQSEVSIjsgLy8g5piO5paHCiAgICBjaGFyIGNpcGhlcnRleHRbMTAyNF0sIHJlc3VsdFsxMDI0XTsKCiAgICAvLyDliqDlr4YKICAgIGVuY3J5cHQoa2V5LCB0ZXh0LCBjaXBoZXJ0ZXh0KTsKICAgIHByaW50ZigiJXNcbiIsIGNpcGhlcnRleHQpOwoKICAgIC8vIOino+WvhgogICAgZGVjcnlwdChrZXksIGNpcGhlcnRleHQsIHJlc3VsdCk7CiAgICBwcmludGYoIiVzXG4iLCByZXN1bHQpOwoJCgkKCXByaW50ZiAoIiBcbioqKiogVGFidWsgVW5pdmVyc2l0eSAgKioqKiBcbiBcbiAqIENvbGxlZ2UgT2YgQ29tcHV0ZXIgQW5kIEluZm9ybWF0aW9uIFRlY2hub2xvZ3kgKiBcbiIgIlxuICogUHJlcGFpcmVkIEJ5OiBcbiIgIlxuICogRmFoZCBEYXlpbSBBbGFuemkgXG4iICJcbiAqIE9tYXIgSWJyYWhpbSBBbG1heWh1YmkgXG4iICJcbiAqIElicmFoaW0gU2FsYWggQWxhbnppIFxuIiAgIlxuICogTmFzc2VyIEF3YWQgIEFscWFkaSBcbiIgIlxuICogS2hhbGlkIEFiZHVsIEthcmltIEFsYW56aSBcbiIgIlxuICogQWxpIEFiZHVsbGFoIGFsQmVsYXdpIFxuIiAiXG4gKioqKioqKiBVbmRlciBzdXBlcnZpc2lvbiAqKioqKioqXG4iICJcbiAqKioqIERyLiBJYnJhaGltIEFsc3NhZGkgKioqKlxuIik7CgogICAgcmV0dXJuIDA7CgkKCQoJCn0KCi8qCiAqIEUoeCkgPSAoYXggKyBiKSBtb2QgbQogKi8KY2hhciBzaGlmdChpbnQgKmtleSwgY2hhciBjaCkKewogICAgaW50IG9mZnNldCA9IGNoIC0gJ0EnOwogICAgcmV0dXJuIChrZXlbMF0gKiBvZmZzZXQgKyBrZXlbMV0pICUgV0lEVEggKyAnQSc7Cn0KCi8qCiAqIEQoeCkgPSBhXnstMX0oeCAtIGIpIG1vZCBtCiAqLwpjaGFyIHVuc2hpZnQoaW50ICprZXksIGNoYXIgY2gpCnsKICAgIGludCBvZmZzZXQgPSBjaCAtICdBJzsKICAgIHJldHVybiAoKChrZXlbMF0gKiAob2Zmc2V0ICsga2V5WzFdKSkgJSBXSURUSCArIFdJRFRIKSAlIFdJRFRIKSArICdBJzsKfQoKLyoKICog5Yik5patIGEg5LiOIGIg5piv5ZCm5LqS57SgCiAqLwppbnQgZ2NkKGludCBhLCBpbnQgYikKewogICAgaW50IHRtcDsKICAgIHdoaWxlIChhICE9IDApCiAgICB7CiAgICAgICAgdG1wID0gYTsKICAgICAgICBhID0gYiAlIGE7CiAgICAgICAgYiA9IHRtcDsKICAgIH0KICAgIHJldHVybiBiOwp9CgovKgogKiDmsYIgYSDlnKjlr4booajkuK3nmoTkuZjms5XpgIYKICovCmludCBtb2RJbnZlcnNlKCBpbnQgYSwgaW50IG0pCnsKICAgIGludCB4MSwgeDIsIHgzLCB5MSwgeTIsIHkzLCB0MSwgdDIsIHQzLCBxOwogICAgeDEgPSB5MiA9IDEsIHgyID0geTEgPSAwOwogICAgeDMgPSAoIGEgPj0gbSApID8gYSA6IG07CiAgICB5MyA9ICggYSA+PSBtICkgPyBtIDogYTsKCiAgICB3aGlsZSAoIDEgKQogICAgewogICAgICAgIGlmICggeTMgPT0gMCApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4geDM7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCB5MyA9PSAxICkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB5MjsKICAgICAgICB9CiAgICAgICAgcSA9IHgzIC8geTM7CiAgICAgICAgdDEgPSB4MSAtIHEgKiB5MSwgdDIgPSB4MiAtIHEgKiB5MiwgdDMgPSB4MyAtIHEgKiB5MzsKICAgICAgICB4MSA9IHkxLCB4MiA9IHkyLCB4MyA9IHkzOwogICAgICAgIHkxID0gdDEsIHkyID0gdDIsIHkzID0gdDM7CiAgICB9Cn0=