tag:blogger.com,1999:blog-11887650561289559582024-03-19T10:07:10.199+05:30the insane techieDhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.comBlogger178125tag:blogger.com,1999:blog-1188765056128955958.post-27838738504435955112022-01-23T20:23:00.000+05:302022-01-23T20:23:22.583+05:30Pandas - Using pandas.melt<span style="font-family: courier;">The <b>pandas.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None, ignore_index=True)</b> function unpivots a DataFrame from wide to long format, optionally leaving identifiers set. </span><div><span style="font-family: courier;">Click <a href="https://pandas.pydata.org/docs/reference/api/pandas.melt.html" target="_blank">here</a> for the documentation.
</span><pre class="python" name="code">
import pandas as pd
import numpy as np
</pre>
<pre class="python" name="code">
df_to_melt = pd.read_csv('to_melt.csv', header=0)
df_to_melt.head()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEij7uDAPCMXT13GwLfhdvfTeH6nWgEBItJoUL2gmLrrmU8pO0CL5pVAbeA_q_FlPtvsIrqsLaWamCFOJ2sc3LMOi-S2f-1CXozmUL5jvvF_RdOpOdHWyyFS76bkroIjFRCn_APJ3hKzxIT8WjtmXEF2lJ4RyVg0MhBoz6XGngS3mydzVnCnarQVoG4J=s600" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="161" data-original-width="600" src="https://blogger.googleusercontent.com/img/a/AVvXsEij7uDAPCMXT13GwLfhdvfTeH6nWgEBItJoUL2gmLrrmU8pO0CL5pVAbeA_q_FlPtvsIrqsLaWamCFOJ2sc3LMOi-S2f-1CXozmUL5jvvF_RdOpOdHWyyFS76bkroIjFRCn_APJ3hKzxIT8WjtmXEF2lJ4RyVg0MhBoz6XGngS3mydzVnCnarQVoG4J=s320" width="320" /></a></div>
<pre class="python" name="code">
## The columns to unpivot will form the entries in the 'variable' column.
## So better to rename them before doing melt
df_to_melt.rename(columns={'BASIC_AMOUNT':'BASIC', 'DA_AMOUNT':'DA',
'HRA_AMOUNT':'HRA', 'SPECIAL_AMOUNT':'SPECIAL'
}, inplace=True)
df_to_melt.columns
</pre><span style="font-family: courier;">
Index(['EMP_NO', 'BASIC', 'DA', 'HRA', 'SPECIAL'], dtype='object')
</span><pre class="python" name="code">
value_cols = df_to_melt.columns[1:]
value_cols
</pre><span style="font-family: courier;">
Index(['BASIC', 'DA', 'HRA', 'SPECIAL'], dtype='object')
</span><pre class="python" name="code">
## If 'value_vars' is not specified, it uses all columns that are not set
## as id_vars. Still, we are passing it for understanding
df_to_melt = pd.melt(df_to_melt, id_vars=['EMP_NO'], value_vars=value_cols,
value_name='AMOUNT', var_name='HEAD')
df_to_melt.head()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhN8Jt-pLW75e4VnOOtSRw7hkpm3264HnW0WPfO8WQkuU9TMFqbYRwIPBq8LPkDd_wq8YlZpMqk9g8JDtejiVJNuOxh4ghFo24wJe9N7Z5T-6Z9dlpAbgA3yowVZZWzzqhS-8WRrRh9qBZZE22I6QS-mrowjNJ1HjsIY6E7EiYxRKdnQx8ZOP8QTQsl=s237" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="150" data-original-width="237" src="https://blogger.googleusercontent.com/img/a/AVvXsEhN8Jt-pLW75e4VnOOtSRw7hkpm3264HnW0WPfO8WQkuU9TMFqbYRwIPBq8LPkDd_wq8YlZpMqk9g8JDtejiVJNuOxh4ghFo24wJe9N7Z5T-6Z9dlpAbgA3yowVZZWzzqhS-8WRrRh9qBZZE22I6QS-mrowjNJ1HjsIY6E7EiYxRKdnQx8ZOP8QTQsl=s200" width="200" /></a></div>
<pre class="python" name="code">
df_to_melt['HEAD'].unique()
</pre><span style="font-family: courier;">
array(['BASIC', 'DA', 'HRA', 'SPECIAL'], dtype=object)</span></div>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-67794806015753825882022-01-23T20:17:00.000+05:302022-01-23T20:17:04.063+05:30Pandas - Using pandas.pivot<span style="font-family: courier;">The <b>pandas.pivot(data, index=None, columns=None, values=None)</b> function returns reshaped DataFrame organized by given index / column values. </span><div><span style="font-family: courier;">Click <a href="https://pandas.pydata.org/docs/reference/api/pandas.pivot.html" target="_blank">here</a> for the documentation.
</span><pre class="python" name="code">
import pandas as pd
import numpy as np
</pre>
<pre class="python" name="code">
df_to_pivot = pd.read_csv('to_pivot.csv', header=0)
df_to_pivot.head()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgdQ_7GGOF907v9Dvfchix7fQcpg8_skWYFgOYKUMBeQg3XUPXgz3usM9e-e3o37u_gIYpaMdusqQNgzaRaP7slpeszuAmjt692piEtTEDig1zg8SAUjsR4cJ1JfEd083wI7GCB0SWQjgjuODb0Fn6Z8ARX8pJRU2IZ1fQ1-lG7D4z554OeBwSvbuQn=s236" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="148" data-original-width="236" src="https://blogger.googleusercontent.com/img/a/AVvXsEgdQ_7GGOF907v9Dvfchix7fQcpg8_skWYFgOYKUMBeQg3XUPXgz3usM9e-e3o37u_gIYpaMdusqQNgzaRaP7slpeszuAmjt692piEtTEDig1zg8SAUjsR4cJ1JfEd083wI7GCB0SWQjgjuODb0Fn6Z8ARX8pJRU2IZ1fQ1-lG7D4z554OeBwSvbuQn=s200" width="200" /></a></div>
<pre class="java" name="code">
df_to_pivot['HEAD'].unique()
</pre><span style="font-family: courier;">
array(['BASIC', 'DA', 'HRA', 'SPECIAL'], dtype=object)
</span><pre class="python" name="code">df_to_pivot = pd.pivot(df_to_pivot, index=['EMP_NO'], columns=['HEAD'],
values=['AMOUNT'])
df_to_pivot.head()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEi6qT3EILmXtXdDwU2UyGTNQ6CqqJRo7o8P-FSTOY4QaP5F0SU6bQYtYPOYtVVj-a3b_sRigtWkUanED9OaLSBjRdNgZ-LgFigQYn6AfnoYbUbyDYNJQH1JDut6JJc9iUuX5GB6dGveGLc2mwmK6r89RD2iJmx4N_cVuaNLw19E6PNM9yooMCSm_Ass=s360" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="202" data-original-width="360" height="179" src="https://blogger.googleusercontent.com/img/a/AVvXsEi6qT3EILmXtXdDwU2UyGTNQ6CqqJRo7o8P-FSTOY4QaP5F0SU6bQYtYPOYtVVj-a3b_sRigtWkUanED9OaLSBjRdNgZ-LgFigQYn6AfnoYbUbyDYNJQH1JDut6JJc9iUuX5GB6dGveGLc2mwmK6r89RD2iJmx4N_cVuaNLw19E6PNM9yooMCSm_Ass=w320-h179" width="320" /></a></div>
<pre class="python" name="code">
df_to_pivot.columns = [str(j) + '_' + str(i) for i, j in df_to_pivot.columns]
df_to_pivot.head()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjBvTwS-0iBjaAke3LCCpcVTygTdc5v-7V5p8BbhSlNotNv5ddidMdWdHvSeH-f-FldKwDb7skbFvYUbCSEusBgHnLWadrpakKz3jPO3GeOUNlajRVRca3gVUabMgzL-afCCfVchqv0YmjyeY6iiwqF5UOCziOkoCP-8iFG07EJn4eGeLIZd9if8i_j=s573" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="186" data-original-width="573" height="104" src="https://blogger.googleusercontent.com/img/a/AVvXsEjBvTwS-0iBjaAke3LCCpcVTygTdc5v-7V5p8BbhSlNotNv5ddidMdWdHvSeH-f-FldKwDb7skbFvYUbCSEusBgHnLWadrpakKz3jPO3GeOUNlajRVRca3gVUabMgzL-afCCfVchqv0YmjyeY6iiwqF5UOCziOkoCP-8iFG07EJn4eGeLIZd9if8i_j=w320-h104" width="320" /></a></div>
<pre class="python" name="code">
df_to_pivot.reset_index(inplace=True)
df_to_pivot
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh9ji1AouPkjFVGlu0hW4XIfcil-HoreireVAq7shVjeW87yX3mSDAXQ0Cs4A7_uvgObTLWMt2N8eV2TeYFtACpO46heyhrio1kDoI2fcNh6qYyQB3A5B2ApzHhINZIFyJhNneKkSId5TORp7j8nYceRxvnSx8HnSdmfEX4K3dm8xnpdTfgIOcCiUQW=s595" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="272" data-original-width="595" height="146" src="https://blogger.googleusercontent.com/img/a/AVvXsEh9ji1AouPkjFVGlu0hW4XIfcil-HoreireVAq7shVjeW87yX3mSDAXQ0Cs4A7_uvgObTLWMt2N8eV2TeYFtACpO46heyhrio1kDoI2fcNh6qYyQB3A5B2ApzHhINZIFyJhNneKkSId5TORp7j8nYceRxvnSx8HnSdmfEX4K3dm8xnpdTfgIOcCiUQW=w320-h146" width="320" /></a></div></div>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-62462996259279237572022-01-23T20:07:00.001+05:302022-01-23T20:08:30.410+05:30Pandas - Place Amount into Buckets
<pre class="python" name="code">
import pandas as pd
import numpy as np
df_salary = pd.read_csv('bucketing.csv', header=0)
df_salary.head()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgZyP4_giSCVv1yE1Phri_h9zMEjWSENvDk-nnh4QfdkF_R5JAEW7fSc-FI6HSf_hX-rVpKOV41lK1lMpneCCNQ8AP09rySnCcY5YIYZufPu3AY1Ckt9ya_HGYJuxZ4Lqa5hcXp-xYt1_yCCGezhstYIWe-TbhJDTVKHqZ4y6gMkFXqeCvVVh2tUFED=s183" style="clear: both; display: block; float: left; padding: 1em 0px; text-align: left;"><img border="0" data-original-height="145" data-original-width="183" height="159" src="https://blogger.googleusercontent.com/img/a/AVvXsEgZyP4_giSCVv1yE1Phri_h9zMEjWSENvDk-nnh4QfdkF_R5JAEW7fSc-FI6HSf_hX-rVpKOV41lK1lMpneCCNQ8AP09rySnCcY5YIYZufPu3AY1Ckt9ya_HGYJuxZ4Lqa5hcXp-xYt1_yCCGezhstYIWe-TbhJDTVKHqZ4y6gMkFXqeCvVVh2tUFED=w200-h159" width="200" /></a></div>
<br />
<pre class="python" name="code">df_salary.shape
</pre>
(109516, 2)
<pre class="python" name="code">
BUCKET_SIZE = 10000 # the difference between the lower and the upper range in each bucket
BUCKET_LOWER_LIMIT = 10000 # the bucket starts here
BUCKET_UPPER_LIMIT = 250000 # the bucket ends here
BUCKET_UNITS = 1000 # the bucket range will be in 1000s
BUCKET_STRING_LENGTH = 3 # prepend zeroes to make the label of length 3
</pre>
<pre class="python" name="code">
col = 'SALARY'
conditions = []
choices = []
conditions.append(df_salary[col].le(BUCKET_LOWER_LIMIT))
choice_str = '<=' + str(int(BUCKET_LOWER_LIMIT/BUCKET_UNITS)).zfill(BUCKET_STRING_LENGTH)
choices.append(choice_str)
current_value = BUCKET_LOWER_LIMIT
next_value = None
while current_value < BUCKET_UPPER_LIMIT:
next_value = current_value + BUCKET_SIZE
if next_value > BUCKET_UPPER_LIMIT:
break
conditions.append(df_salary[col].between(current_value, next_value))
choice_str = str(int(current_value/BUCKET_UNITS)).zfill(BUCKET_STRING_LENGTH) + '-' + str(int(next_value/BUCKET_UNITS)).zfill(BUCKET_STRING_LENGTH)
choices.append(choice_str)
current_value = next_value
##--------------------------------------------------------------------------------------------------------
## crossing the upper limit may omit a bucket in-between
if next_value > BUCKET_UPPER_LIMIT:
current_value = next_value - BUCKET_SIZE
next_value = BUCKET_UPPER_LIMIT
conditions.append(df_salary[col].between(current_value, next_value))
choice_str = str(int(current_value/BUCKET_UNITS)).zfill(BUCKET_STRING_LENGTH) + '-' + str(int(next_value/BUCKET_UNITS)).zfill(BUCKET_STRING_LENGTH)
choices.append(choice_str)
##--------------------------------------------------------------------------------------------------------
conditions.append(df_salary[col].gt(BUCKET_UPPER_LIMIT))
choice_str = '>' + str(int(BUCKET_UPPER_LIMIT/BUCKET_UNITS)).zfill(BUCKET_STRING_LENGTH)
choices.append(choice_str)
print('Buckets: ', choices)
df_salary['BUCKET'] = np.select(conditions, choices, default=np.nan)
</pre><span style="font-family: courier;">
Buckets: ['<=010', '010-020', '020-030', '030-040', '040-050', '050-060', '060-070', '070-080', '080-090', '090-100', '100-110', '110-120', '120-130', '130-140', '140-150', '150-160', '160-170', '170-180', '180-190', '190-200', '200-210', '210-220', '220-230', '230-240', '240-250', '>250']
</span><pre class="python" name="code">
df_salary.head()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjvUgM2gsW0gWFJARLgiLNCmZV0Md67MbJ9Nk-lOs6f3wcsvKNqPFxM-a9SGdbKR9zvhQctFd2n2j7KHNjh29S3Q4eeid3e-pEisjjzo7hthZqui3YuDtPDhwDnqi7-M63POUShPN6jzKdnIoSn5UtBUmOOSYYMe2h0AczgaFR_J2xvWR5TTbpTxK0L=s252" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="142" data-original-width="252" src="https://blogger.googleusercontent.com/img/a/AVvXsEjvUgM2gsW0gWFJARLgiLNCmZV0Md67MbJ9Nk-lOs6f3wcsvKNqPFxM-a9SGdbKR9zvhQctFd2n2j7KHNjh29S3Q4eeid3e-pEisjjzo7hthZqui3YuDtPDhwDnqi7-M63POUShPN6jzKdnIoSn5UtBUmOOSYYMe2h0AczgaFR_J2xvWR5TTbpTxK0L=s200" width="200" /></a></div>
<pre class="python" name="code">
## The order of conditions is such that the border values (multiples of the bucket size i.e. 10000)
## will be considered in the lower bucket. eg. 50000 will take '040-050' and not '050-060'
df_salary.loc[(df_salary['SALARY']%BUCKET_SIZE == 0)]
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEg3EdcUcGjd6YX3UwUsjAwfS1KAZb20CMl8Nh2gBvn--BYpxFAQXExFW1Xmb4dBuHc0k_0p7ax3mUiSm3bPbRuxHNk_LuzK0Yx3u5iJzx194pqw3SQc1NM9BdWyGa91TsM8mZuXBwG_IlZeZOfwB4c38N-hltg_JvecM3vFCUIW5eIvAT7oFg-32--E=s322" style="clear: left; display: block; float: left; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="322" data-original-width="302" height="200" src="https://blogger.googleusercontent.com/img/a/AVvXsEg3EdcUcGjd6YX3UwUsjAwfS1KAZb20CMl8Nh2gBvn--BYpxFAQXExFW1Xmb4dBuHc0k_0p7ax3mUiSm3bPbRuxHNk_LuzK0Yx3u5iJzx194pqw3SQc1NM9BdWyGa91TsM8mZuXBwG_IlZeZOfwB4c38N-hltg_JvecM3vFCUIW5eIvAT7oFg-32--E=s200" /></a></div>
<pre class="python" name="code">
df_salary.groupby(['BUCKET']).size()
</pre>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjuJd07gzNYu54_Vz6dlrUDL0Lq3AyYCV_lwrM99b1bpsPvfk7rR2zMlf8OLcyIN--ZtBDf_PlamqUQzPungfVDdI8puLcGQX2JDUyzbODqVGz03mYEwr7Z88g6ExVf7UExjQrrW4hDYW5vfa4guiH_ACDuprqC4FAdIiuTXgPP_HVEpGgBUnjYN6g0=s629" style="clear: left; display: block; float: left; margin-bottom: 1em; margin-right: 1em; padding: 1em 0px; text-align: left;"><img alt="" border="0" data-original-height="629" data-original-width="158" height="200" src="https://blogger.googleusercontent.com/img/a/AVvXsEjuJd07gzNYu54_Vz6dlrUDL0Lq3AyYCV_lwrM99b1bpsPvfk7rR2zMlf8OLcyIN--ZtBDf_PlamqUQzPungfVDdI8puLcGQX2JDUyzbODqVGz03mYEwr7Z88g6ExVf7UExjQrrW4hDYW5vfa4guiH_ACDuprqC4FAdIiuTXgPP_HVEpGgBUnjYN6g0=s200" /></a></div>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-90932786807239400142020-09-27T21:41:00.005+05:302020-11-01T10:20:50.851+05:30Regex - Cheatsheet<div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj6VDz7zXDD7blcZNOdVqwCU0TwRsHkbmTfNtRoHu_On2WH5Onwtb7FI1T_OxNqCehN2qSq6vgJO_46UEUouFwO-mAqtV52UL7OnfMtPebfc1Zg1P0HFCIbWTvU7oLNDCd4zKzTUjF_Yw/s1344/regex.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="526" data-original-width="1344" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj6VDz7zXDD7blcZNOdVqwCU0TwRsHkbmTfNtRoHu_On2WH5Onwtb7FI1T_OxNqCehN2qSq6vgJO_46UEUouFwO-mAqtV52UL7OnfMtPebfc1Zg1P0HFCIbWTvU7oLNDCd4zKzTUjF_Yw/w640-h250/regex.png" width="640" /></a></div><br /><b><br /></b></div><b>Character classes</b>
<table>
<tbody><tr><td>.</td><td> </td><td>any character except newline</td></tr>
<tr><td>\w \d \s</td><td> </td><td>word, digit, whitespace</td></tr>
<tr><td>\W \D \S</td><td> </td><td>not word, digit, whitespace</td></tr>
<tr><td>[abc]</td><td> </td><td>any of a, b, or c</td></tr>
<tr><td>[^abc]</td><td> </td><td>not a, b, or c</td></tr>
<tr><td>[a-g]</td><td> </td><td>character between a & g</td></tr>
</tbody></table>
<br />
<b>Anchors</b>
<table>
<tbody>
<tr><td>^abc$</td><td> </td><td>start / end of the string</td></tr>
<tr><td>\b \B</td><td> </td><td>word, not-word boundary</td></tr>
</tbody>
</table>
<br />
<b>Escaped characters</b>
<table>
<tbody>
<tr><td>\. \* \\</td><td> </td><td>escaped special characters</td></tr>
<tr><td>\t \n \r</td><td> </td><td>tab, linefeed, carriage return</td></tr>
</tbody>
</table>
<br />
<b>Groups & Lookaround</b>
<table>
<tbody>
<tr><td>(abc)</td><td> </td><td>capture group</td></tr>
<tr><td>\1</td><td> </td><td>backreference to group #1</td></tr>
<tr><td>(?:abc)</td><td> </td><td>non-capturing group</td></tr>
<tr><td>(?=abc)</td><td> </td><td>positive lookahead</td></tr>
<tr><td>(?!abc)</td><td> </td><td>negative lookahead</td></tr>
</tbody>
</table>
<br />
<b>Quantifiers & Alternation</b>
<table>
<tbody>
<tr><td>a* a+ a?</td><td> </td><td>0 or more, 1 or more, 0 or 1</td></tr>
<tr><td>a{5} a{2,}</td><td> </td><td>exactly five, two or more</td></tr>
<tr><td>a{1,3}</td><td> </td><td>between one & three</td></tr>
<tr><td>a+? a{2,}?</td><td> </td><td>match as few as possible</td></tr>
<tr><td>ab|cd</td><td> </td><td>match ab or cd</td></tr>
</tbody>
</table>
<br /><span face=""source sans pro", Helvetica, sans-serif" style="background-color: white; color: #333333; font-size: 16px; text-align: justify;">Ref: </span><a href="https://regexr.com/" style="background-color: white; border-bottom: 1px dotted rgba(160, 160, 160, 0.65); box-sizing: border-box; font-family: "source sans pro", Helvetica, sans-serif; font-size: 16px; text-align: justify; text-decoration-line: none; transition: color 0.2s ease 0s, border-bottom-color 0.2s ease 0s;">regexr.com</a>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-87069992283864997822020-05-07T14:35:00.009+05:302020-11-01T10:22:19.227+05:30ROS In Docker Container<div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><br /></div></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZJ7PdSygwlpJbPElLarE6-J4vSH-R0XSOcss2kyGUREv4MoZPTlRE46OlXIOtpQDK4eDyhxRM8Ig16nvUNKqwa5MMfV3JkQUKRxsSqKlX-tRfR3dk-AJ-PKR0OzF32Yb4gAg1YRZdjuM/s1920/1920px-Docker_%2528container_engine%2529_logo.svg.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="456" data-original-width="1920" height="48" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZJ7PdSygwlpJbPElLarE6-J4vSH-R0XSOcss2kyGUREv4MoZPTlRE46OlXIOtpQDK4eDyhxRM8Ig16nvUNKqwa5MMfV3JkQUKRxsSqKlX-tRfR3dk-AJ-PKR0OzF32Yb4gAg1YRZdjuM/w200-h48/1920px-Docker_%2528container_engine%2529_logo.svg.png" width="200" /></a></div></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd3x7lPtN8nHOWq8oe1tKc04dA-MbHNoEVc_lmd8Hk37lmCxOLZFA75Fm6ccOntZwCNK_EJjN7B94BiA29najFOXkuOMLDMc-0KvZlXTgDczSwAsgmCGSP2fVg2vqM3C9Lx5Lj-UKHIQM/s300/300px-Ros_logo.svg.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="80" data-original-width="300" height="54" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd3x7lPtN8nHOWq8oe1tKc04dA-MbHNoEVc_lmd8Hk37lmCxOLZFA75Fm6ccOntZwCNK_EJjN7B94BiA29najFOXkuOMLDMc-0KvZlXTgDczSwAsgmCGSP2fVg2vqM3C9Lx5Lj-UKHIQM/w200-h54/300px-Ros_logo.svg.png" width="200" /></a><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<span face=""verdana" , sans-serif">ROS (Robot Operating System) - Documentation - <a href="http://wiki.ros.org/">http://wiki.ros.org/</a></span><br />
<span face=""verdana" , sans-serif"><br /></span>
<br />
<span face=""verdana" , sans-serif">In this example I use docker image of ROS Melodic and a Dockerfile for creating the required docker container. Python3 (python3.7) is also installed in this example. </span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif"><span face=""verdana" , sans-serif">Please refer </span><a href="https://docs.docker.com/get-started/">https://docs.docker.com/get-started/</a> for more information on Dockers.</span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">(1) Pull the docker image for ROS Melodic</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span>
<br />
<pre><span style="font-family: "courier new" , "courier" , monospace;"> docker pull ros:melodic</span></pre>
<br />
<span face=""verdana" , sans-serif">(2) Creating the Dockerfile</span><br />
<pre></pre>
<pre><span style="font-family: "courier new" , "courier" , monospace;">FROM ros:melodic
MAINTAINER dhanoopbhaskar@gmail.com
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y software-properties-common \
&& add-apt-repository ppa:deadsnakes/ppa \
&& apt-get install -y python3.7</span></pre>
<pre><span style="font-family: "courier new" , "courier" , monospace;">
RUN apt-get update && apt-get install -y \
python-pip \
python3-pip \
python3-all-dev
</span></pre>
<pre><span style="font-family: "courier new" , "courier" , monospace;">RUN apt-get install -y \
python3-rospkg*
</span></pre>
<pre><span style="font-family: "courier new" , "courier" , monospace;">RUN apt-get update --fix-missing
RUN dpkg --configure -a
RUN apt-get install -f
RUN apt-get install -y \
ros-melodic-desktop-full --fix-missing
RUN apt-get install -y python-catkin-tools
</span></pre>
<pre><span style="font-family: "courier new" , "courier" , monospace;">RUN apt-get install --no-install-recommends --no-install-suggests -y \
build-essential \
cmake \
python3.7-dev \
&& rm -rf /var/lib/apt/lists/*
</span></pre>
<pre><span style="font-family: "courier new" , "courier" , monospace;">RUN python -m pip install --upgrade pip
RUN python2 -m pip install --upgrade pip
RUN python3 -m pip install --upgrade pip
RUN pip3 install --upgrade pip
RUN pip3 install --upgrade setuptools
RUN python3.7 -m pip install --upgrade pip
RUN python3.7 -m pip install --upgrade setuptools
</span>
<span face=""verdana" , sans-serif"></span></pre>
<span face=""verdana" , sans-serif">(3) Now create the docker using this Dockerfile and run 😊 (Refer documentation for more information)</span><br />
<span face=""verdana" , sans-serif"><br /></span>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-82140456558246847252020-05-07T14:07:00.004+05:302020-11-01T10:22:42.060+05:30Working With Python 3 In ROS Kinetic Or Melodic<div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXNkwcrQ0fLVAPSzQAqnReWcKrn5W0QBI4bAYKIir295pjXKdkNhHmlqMeLdJMXrk13y8fZ0kyvNdp6QzftTfaD4OX5Tpe5nQaU0nGM7JDLBSutLPCs68ObPCiXOn_EqDOdA-7l1F8mhs/s200/python-icon-200x200.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="200" data-original-width="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXNkwcrQ0fLVAPSzQAqnReWcKrn5W0QBI4bAYKIir295pjXKdkNhHmlqMeLdJMXrk13y8fZ0kyvNdp6QzftTfaD4OX5Tpe5nQaU0nGM7JDLBSutLPCs68ObPCiXOn_EqDOdA-7l1F8mhs/s0/python-icon-200x200.png" /></a></div><br /><span face=""verdana" , sans-serif"><br /></span><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVQniGsvEq4bmk1yx_G1KUpefSVT7Q7aGfDuQvanYQu6MzCHaTpGKUxERvG9yFliqJHYkO-d2TdUEBZGWe02-uI5j1XmPsKfZGyK_uiXY5QB7hrSbwz_0eBtvUuKWT5WMJx-z1iXGVRNU/s300/300px-Ros_logo.svg.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="80" data-original-width="300" height="107" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVQniGsvEq4bmk1yx_G1KUpefSVT7Q7aGfDuQvanYQu6MzCHaTpGKUxERvG9yFliqJHYkO-d2TdUEBZGWe02-uI5j1XmPsKfZGyK_uiXY5QB7hrSbwz_0eBtvUuKWT5WMJx-z1iXGVRNU/w400-h107/300px-Ros_logo.svg.png" width="400" /></a></div></div><span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">ROS (Robot Operating System) - Documentation - <a href="http://wiki.ros.org/">http://wiki.ros.org/</a>
</span><br />
<span face=""verdana" , sans-serif"><span style="background-color: white; color: #353535; font-size: 14px; white-space: normal;"><br /></span>
<span style="background-color: white; color: #353535; font-size: 14px; white-space: normal;"><br /></span>
<span style="background-color: white; color: #353535; font-size: 14px; white-space: normal;">The Robot Operating System (ROS) is a flexible framework for writing robot software. It is a collection of tools, libraries, and conventions that aim to simplify the task of creating complex and robust robot behavior across a wide variety of robotic platforms. (Ref. </span><a href="https://www.ros.org/about-ros/">https://www.ros.org/</a>)
</span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">ROS (upto Melodic) officially supports only python2 and <u>NOT python3</u>. However some libraries we use in our projects (eg. Speech Recognition using Google Cloud Speech) may require <b>python3</b> to run.</span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">If ROS needs to support python3 we may have to recompile ROS source code using python3 which is <u>not practical.</u></span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">So what we can do is to run python3 programs, separately and connect using <u>ROS bridge</u>. (if we use custom messages (<a href="http://wiki.ros.org/msg">ROS msg</a>)</span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">However, <i><u><b>if we are not using any custom rosmsg</b></u></i> and using only built-in rosmsg, we can do the following steps to run python3 codes in ROS (without using a ROS bridge.)</span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">Install ROS (here I install Melodic)</span><br />
<pre><span face=""verdana" , sans-serif"> </span><span style="font-family: "courier new" , "courier" , monospace;">apt install ros-melodic-desktop-full</span></pre>
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">After installing ROS, install rospkg for python3</span><br />
<pre><span face=""verdana" , sans-serif"> </span><span style="font-family: "courier new" , "courier" , monospace;">apt install python3-pip python3-all-dev python3-rospkg</span></pre>
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">This will prompt to install python3-rospkg and to remove ROS packages (already installed). Select Yes for that prompt. This will remove ROS packages and we will have to re-install them.</span><br />
<pre><span face=""verdana" , sans-serif"> </span><span style="font-family: "courier new" , "courier" , monospace;">apt install ros-melodic-desktop-full --fix-missing</span></pre>
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">This will complete the installation part. Now comes the coding part.</span><br />
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">Just include the following directive as the first line of your program code (file) which should be executed using python3.</span><br />
<pre><span face=""verdana" , sans-serif"> </span><span style="font-family: "courier new" , "courier" , monospace;">#!/usr/bin/env python3</span></pre>
<span face=""verdana" , sans-serif"><br /></span>
<span face=""verdana" , sans-serif">We can now execute everything as we do </span><span face=""verdana" , sans-serif">normally</span><span face=""verdana" , sans-serif"> in ROS. </span><br />
<span face=""verdana" , sans-serif">Read the documentation (link is given above) for more information on ROS. </span><br />
<span face=""verdana" , sans-serif"><br /></span>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-35072874750856673492019-10-28T12:10:00.003+05:302020-11-01T10:23:06.742+05:30Biped Walking Robot<div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuCHK2VMTo7UltNSR0U3KRw6B4iYy1RkI4z3zyHTDUrOWdunsy6dwuDJLNCyCW4oXO1Ma9Is4C3MgfOCbSGcUPWr_DTEgkhaI0UV-MPnbYdaX2xZKsjdsWDmfnBe_wUGSJQzTEdPQtmd8/s1366/biped-walking.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1366" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuCHK2VMTo7UltNSR0U3KRw6B4iYy1RkI4z3zyHTDUrOWdunsy6dwuDJLNCyCW4oXO1Ma9Is4C3MgfOCbSGcUPWr_DTEgkhaI0UV-MPnbYdaX2xZKsjdsWDmfnBe_wUGSJQzTEdPQtmd8/w640-h360/biped-walking.png" width="640" /></a></div><br /><i><br /></i></div><div><i><br /></i></div><i>We, a team of 3, attended a course titled "2 Mechatronics Project" conducted by Skyfi Labs in the month of October 2019. </i><br />
<i>Thought of sharing the assignments done as a part of the course.
</i>
<br />
<br />
<b><i>Biped Walking Robot</i></b>
<br />
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/yhSSDe5Mt0g" width="560"></iframe>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-34842537703699579522019-10-28T12:05:00.002+05:302020-11-01T10:23:32.336+05:30Robotic Arm<div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZugsxkYzgMp7ehWKtdZuAFaC_7vRNsm9MAZJavuTllxlYQ3paNEWa1NgQ0g8Kizf5GIu3Rj6AGal_8e86JQcqB9-aD5kpXRZ7b9ExIAtWegNvDtbKKOj7qwxMA0myqAEtxpoDVfhOUBU/s1366/robotic-arm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1366" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZugsxkYzgMp7ehWKtdZuAFaC_7vRNsm9MAZJavuTllxlYQ3paNEWa1NgQ0g8Kizf5GIu3Rj6AGal_8e86JQcqB9-aD5kpXRZ7b9ExIAtWegNvDtbKKOj7qwxMA0myqAEtxpoDVfhOUBU/w640-h360/robotic-arm.png" width="640" /></a></div><br /><i><br /></i></div><i><div><i><br /></i></div>We, a team of 3, attended a course titled "2 Mechatronics Project" conducted by Skyfi Labs in the month of October 2019. </i><br />
<i>Thought of sharing the assignments done as a part of the course.
</i>
<br />
<br />
<b><i>Robotic Arm</i></b>
<br />
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/UdRfddVTSiQ" width="560"></iframe>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-10078253469972123642019-10-28T12:00:00.003+05:302020-11-01T10:23:50.804+05:307 Robots in 6 Days<div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYB_yYlXYRJT5p1hT-m3oCkzCDby60Kc05rKgKu_Z57a4s1LKdyRuTk5_XhtOIe0J1K6oLLPRO_96vbDA-XC4MrMj74xrpwgzB0nSIv06Pshk-Y4n-l03XWvbTbDDf7JkGl8ADlhdn3CQ/s1366/swarm-robots.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1366" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYB_yYlXYRJT5p1hT-m3oCkzCDby60Kc05rKgKu_Z57a4s1LKdyRuTk5_XhtOIe0J1K6oLLPRO_96vbDA-XC4MrMj74xrpwgzB0nSIv06Pshk-Y4n-l03XWvbTbDDf7JkGl8ADlhdn3CQ/w640-h360/swarm-robots.png" width="640" /></a></div><br /><b><br /></b></div><div><b><br /></b></div><b>7 Robots in 6 Days </b><br />
<b><i><br /></i></b>
<i>We, a team of 3, attended a course titled "7 Robots in 6 Days" conducted by Skyfi Labs in the month of June 2019.
</i><br />
<i>Thought of sharing the assignments done as a part of the course.
</i><br />
<i><br /></i><b><i>1. Line Follower Robot using Arduino</i> </b><div><br /></div><div><iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/2kNGa3-BZ-s" width="560"></iframe>
<br />
<br /><br />
<b><i>2. Obstacle Avoider Robot using Arduino</i></b></div><div><br /></div><div><b>
</b>
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/p_MRWmTWcdo" width="560"></iframe>
<br />
<br /><br />
<b><i>3. Obstacle Follower Robot using Arduino</i></b></div><div><br /></div><div><b>
</b>
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/0cTW66jN3gA" width="560"></iframe>
<br /><br /><br />
<b><i>4. Gesture Based Robotics</i></b></div><div><b><i><br /></i></b><div><b>
</b>
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/4X62RCZIvlE" width="560"></iframe>
<br />
<br /><br />
<b><i>5. Mobile Controlled Robot</i></b></div><div><b><i><br /></i></b><div><b>
</b>
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/0o8Xv3cnA5s" width="560"></iframe>
<br />
<br /><br />
<b><i>6. Swarm Robotics</i></b></div><div><b><i><br /></i></b><div><b>
</b>
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/o6P4Hi3LvhA" width="560"></iframe>
<br />
<br /><br />
<b><i>7. Maze Solver Robot using Arduino</i></b></div><div><b><i><br /></i></b><div><b>
</b>
<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/mCsNXq0ujTM" width="560"></iframe>
</div></div></div></div></div>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-32297804038550800852018-07-02T20:01:00.001+05:302020-11-01T10:24:10.180+05:30Mounting an iPhone to Linux Mint as an external drive to copy images and videos<blockquote>
</blockquote>
<br />
<b>Phone: iPhone SE</b><br />
<b>Operating System: Linux Mint 18.1</b>(should work in Ubuntu as well)<br />
<br />
It is done by compiling most of the sources yourself.<br />
Only one library - usbmuxd - must be installed as <b>root</b><br />
All others are installed in the home account.<br />
<br />
Install necessary software for building the source packages.<br />
<br />
To check-out and compile the needed packages from source, you have to install <b>git</b> first.<br />
<br />
Open a terminal and do the following:<br />
<br />
<pre>:~$ sudo apt-get install -y git</pre>
<pre>:~$ sudo apt-get install -y build-essential</pre>
<pre>:~$ sudo apt-get install -y libtool m4 automake</pre>
<pre>:~$ sudo apt-get install -y libfuse-dev</pre>
<br />
All new commands to mount and unmount the file-system of your iPhone, will be installed in the sub-directory "${HOME}/usr/bin/".<br />
<br />
Create the sub-directory to store the source files of the packages to be compiled:<br />
<br />
<pre>:~$ mkdir -p "$HOME/usr/src"</pre>
<br />
Set all required environment variables to ensure to build the packages from source as desired:<br />
<br />
<pre>
:~$ export PKG_CONFIG_PATH="${HOME}/usr/lib/pkgconfig:${PKG_CONFIG_PATH}"
:~$ export CPATH="${HOME}/usr/include:${CPATH}"
:~$ export MANPATH="${HOME}/usr/share/man:${MANPATH}"
:~$ export PATH="${HOME}/usr/bin:${PATH}"
:~$ export LD_LIBRARY_PATH="${HOME}/usr/lib:${LD_LIBRARY_PATH}"
</pre>
<br />
Now put the last two export statements into your .bashrc, to be loaded every time you open a new terminal, otherwise you must type:<br />
<br />
<pre>:~$ export PATH="${HOME}/usr/bin:${PATH}"
:~$ export LD_LIBRARY_PATH="${HOME}/usr/lib:${LD_LIBRARY_PATH}"
</pre>
<br />
whenever you open a new terminal.<br />
<br />
Clone all needed repositories from Github.<br />
<br />
<pre>:~$ cd ~/usr/src
:~$ for x in libplist libusbmuxd usbmuxd libimobiledevice ifuse; do git clone https://github.com/libimobiledevice/${x}.git;done
</pre>
<br />
<br />
Build and install the packages in the following order.<br />
<br />
Build <b>libplist</b><br />
<pre>:~$ cd ~/usr/src/libplist
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install
</pre>
<br />
Build <b>libusbmuxd</b><br />
<pre>:~$ cd ~/usr/src/libusbmuxd
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install
</pre>
<br />
Build <b>libimobiledevice</b><br />
<pre>:~$ cd ~/usr/src/libimobiledevice
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install
</pre>
<br />
Build <b>usbmuxd</b><br />
<i>(The package usbmuxd must be installed with administrative rights, because it needs write access to "/lib/udev/rules.d" and "/lib/systemd/system")</i><br />
<pre>:~$ cd ~/usr/src/usbmuxd
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && sudo make install
</pre>
<br />
Build <b>ifuse</b><br />
<pre>:~$ cd ~/usr/src/ifuse
:~$ ./autogen.sh --prefix="$HOME/usr"
:~$ make && make install
</pre>
<br />
<br />
<b><u>TESTING</u></b><br />
<br />
It's assumed that you put the two exports into your ~/.bashrc as mentioned above.<br />
Open a new terminal.<br />
<br />
Connect your iPhone<br />
<br />
Create a mount point, where you want the content of your iPhone to appear.<br />
<br />
<pre>:~$ mkdir -p ~/usr/mnt</pre>
<br />
<br />
Connect your iPhone to the computer and try to pair the iPhone with your computer.<br />
<br />
<pre>:~$ idevicepair pair</pre>
<br />
<br />
If error occurs during validation, please enter the passcode on the device and retry. A trust dialog will be appeared on your device.
You have to accept it as well<br />
<br />
<pre>:~$ idevicepair pair</pre>
<br />
<br />
After successfully pairing the device, mount the file-system of your iPhone and check the content<br />
<br />
<pre>:~$ ifuse ~/usr/mnt/
:~$ ls ~/usr/mnt/
</pre>
<br />
<br />
To safely disconnect your iPhone, you have to unmount the file-system in ~/usr/mnt first with fusermount.<br />
<br />
<pre>:~$ fusermount -u ~/usr/mnt
</pre>
<br />
<br />
Now, you can plug-off your iPhone again.<br />
<br />
<br />
<u><b>ERRORS AND SOLUTIONS</b></u><br />
<br />
(1) configure: error:<br />
OpenSSL support explicitly requested but OpenSSL could not be found<br />
<br />
<pre>:~$ sudo apt-get install libssl-dev</pre>
<br />
(2) configure: error:<br />
<span style="text-align: justify;">Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LDFLAGS environment variable.</span><br />
<span style="text-align: justify;">Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"</span><br />
<div style="text-align: justify;">
<i>(You probably have to install the development version of the Python package for your distribution. The exact name of this package varies among them.)</i></div>
<br />
<pre>:~$ sudo apt-get install python-dev</pre>
<br />
<br />Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-29050844106827488362016-08-22T20:13:00.002+05:302020-11-01T10:24:30.824+05:30RESTful Web Services in JavaRead about <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST here...</a><br />
In the example program REST is implemented using Jersey Framework.<br />
Download Jersey framework from <a href="https://jersey.java.net/">here...</a>
<br />
I used <b>Dynamic Web Project</b> in <b>Eclipse</b> for coding.
Extract jersey zip file and copy all the <b>.jar</b> files from <b>api</b>, <b>ext</b>, <b>lib</b> folders to <b>WebContent/WEB-INF/lib</b> folder.
<br />
<br />
<b><u>Employee.java</u></b>
<br />
<pre class="java" name="code">
package in.theinsanetechie.rest;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "employee")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private int empcode;
private String name;
private String designation;
private float basicpay;
public Employee() {
}
public Employee(int empcode, String name, String designation, float basicpay) {
super();
this.empcode = empcode;
this.name = name;
this.designation = designation;
this.basicpay = basicpay;
}
public int getEmpcode() {
return empcode;
}
@XmlElement
public void setEmpcode(int empcode) {
this.empcode = empcode;
}
public String getName() {
return name;
}
@XmlElement
public void setName(String name) {
this.name = name;
}
public String getDesignation() {
return designation;
}
@XmlElement
public void setDesignation(String designation) {
this.designation = designation;
}
public float getBasicpay() {
return basicpay;
}
@XmlElement
public void setBasicpay(float basicpay) {
this.basicpay = basicpay;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (Float.floatToIntBits(basicpay) != Float
.floatToIntBits(other.basicpay))
return false;
if (designation == null) {
if (other.designation != null)
return false;
} else if (!designation.equals(other.designation))
return false;
if (empcode != other.empcode)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
</pre>
<br />
<br />
<b><u>EmployeeAccessObject.java</u></b>
<br />
<pre class="java" name="code">
package in.theinsanetechie.rest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
public class EmployeeAccessObject {
private String fileName = "Employee.dat";
@SuppressWarnings("unchecked")
public List<employee> getFullList() {
List<employee> list = null;
File file = new File(fileName);
try {
if (file.exists()) {
FileInputStream fileInputStream = new FileInputStream(file);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
list = (List<employee>) objectInputStream.readObject();
objectInputStream.close();
} else{
Employee employee = new Employee(1001, "The Insane Techie", "Dev", 99999.99f);
list = new ArrayList<employee>();
list.add(employee);
saveList(list);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return list;
}
public Employee get(int empcode) {
List<employee> list = getFullList();
for (Employee temp : list) {
if (temp.getEmpcode() == empcode) {
return temp;
}
}
return null;
}
public boolean addToList(Employee emp){
List<employee> list = getFullList();
boolean exists = false;
for(Employee temp: list){
if(temp.getEmpcode() == emp.getEmpcode()){
exists = true;
break;
}
}
if(!exists){
list.add(emp);
saveList(list);
return true;
}
return false;
}
public boolean updateList(Employee emp){
List<employee> list = getFullList();
for(Employee temp: list){
if(temp.getEmpcode() == emp.getEmpcode()){
int index = list.indexOf(temp);
list.set(index, emp);
saveList(list);
return true;
}
}
return false;
}
public boolean deleteFromList(int empcode){
List<employee> list = getFullList();
for(Employee temp: list){
if(temp.getEmpcode() == empcode){
int index = list.indexOf(temp);
list.remove(index);
saveList(list);
return true;
}
}
return false;
}
private void saveList(List<employee> list) {
File file = new File(fileName);
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(list);
objectOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
</employee></employee></employee></employee></employee></employee></employee></employee></employee></pre>
<br />
<br />
<b><u>EmployeeService.java</u></b>
<br />
<pre class="java" name="code">
package in.theinsanetechie.rest;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
@Path("/EmployeeService")
public class EmployeeService {
EmployeeAccessObject accessObject = new EmployeeAccessObject();
private static final String SUCCESS = "<result>success</result>";
private static final String FAILURE = "<result>failure</result>";
@GET
@Path("/employees")
@Produces(MediaType.APPLICATION_XML)
public List<employee> getFullList(){
return accessObject.getFullList();
}
@GET
@Path("/employees/{empcode}")
@Produces(MediaType.APPLICATION_XML)
public Employee get(@PathParam("empcode") int empcode){
return accessObject.get(empcode);
}
@PUT
@Path("/employees")
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String add(@FormParam("empcode") int empcode,
@FormParam("name") String name,
@FormParam("designation") String designation,
@FormParam("basicpay") float basicpay,
@Context HttpServletResponse servletResponse) throws IOException{
Employee emp = new Employee(empcode, name, designation, basicpay);
boolean result = accessObject.addToList(emp);
if(result == true){
return SUCCESS;
}
return FAILURE;
}
@POST
@Path("/employees")
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String update(@FormParam("empcode") int empcode,
@FormParam("name") String name,
@FormParam("designation") String designation,
@FormParam("basicpay") float basicpay,
@Context HttpServletResponse servletResponse) throws IOException{
Employee emp = new Employee(empcode, name, designation, basicpay);
boolean result = accessObject.updateList(emp);
if(result == true){
return SUCCESS;
}
return FAILURE;
}
@DELETE
@Path("/employees/{empcode}")
@Produces(MediaType.APPLICATION_XML)
public String deleteUser(@PathParam("empcode") int empcode){
boolean result = accessObject.deleteFromList(empcode);
if(result == true){
return SUCCESS;
}
return FAILURE;
}
@OPTIONS
@Path("/employees")
@Produces(MediaType.APPLICATION_XML)
public String getSupportedOperations(){
return "<operations>GET, PUT, POST, DELETE</operations>";
}
}
</employee></pre>
<br />
<br />
<b><u>WebServiceTester.java</u></b>
<br />
<pre class="java" name="code">
package in.theinsanetechie.rest;
import java.util.List;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
public class WebServiceTester {
private Client client;
private String REST_SERVICE_URL = "http://localhost:8080/EmployeeManagement/rest/EmployeeService/employees";
private static final String SUCCESS="<result>success</result>";
private static final String PASS = "pass";
private static final String FAIL = "fail";
private void init(){
this.client = ClientBuilder.newClient();
}
public static void main(String[] args){
WebServiceTester tester = new WebServiceTester();
tester.init();
tester.testGetFullList();
tester.testGet();
tester.testUpdate();
tester.testAdd();
tester.testDelete();
}
private void testGetFullList(){
GenericType<list mployee="">> list = new GenericType<list mployee="">>() {};
List<employee> employees = client
.target(REST_SERVICE_URL)
.request(MediaType.APPLICATION_XML)
.get(list);
String result = PASS;
if(employees.isEmpty()){
result = FAIL;
}
System.out.println("Test case name: testGetFullList, Result: " + result );
}
private void testGet(){
Employee sampleEmp = new Employee();
sampleEmp.setEmpcode(1001);
Employee emp = client
.target(REST_SERVICE_URL)
.path("/{empcode}")
.resolveTemplate("empcode", 1001)
.request(MediaType.APPLICATION_XML)
.get(Employee.class);
String result = FAIL;
if(sampleEmp != null && sampleEmp.getEmpcode() == emp.getEmpcode()){
result = PASS;
}
System.out.println("Test case name: testGet, Result: " + result );
}
private void testUpdate(){
Form form = new Form();
form.param("empcode", "1001");
form.param("name", "Dhanoop Bhaskar");
form.param("designation", "Computer Scientist");
form.param("basicpay", "100000.00f");
String callResult = client
.target(REST_SERVICE_URL)
.request(MediaType.APPLICATION_XML)
.post(Entity.entity(form,
MediaType.APPLICATION_FORM_URLENCODED_TYPE),
String.class);
String result = PASS;
if(!SUCCESS.equals(callResult)){
result = FAIL;
}
System.out.println("Test case name: testUpdate, Result: " + result );
}
private void testAdd(){
Form form = new Form();
form.param("empcode", "1002");
form.param("name", "The Insane Techie");
form.param("designation", "Computer Scientist");
form.param("basicpay", "100000.00f");
String callResult = client
.target(REST_SERVICE_URL)
.request(MediaType.APPLICATION_XML)
.put(Entity.entity(form,
MediaType.APPLICATION_FORM_URLENCODED_TYPE),
String.class);
String result = PASS;
if(!SUCCESS.equals(callResult)){
result = FAIL;
}
System.out.println("Test case name: testAdd, Result: " + result );
}
private void testDelete(){
String callResult = client
.target(REST_SERVICE_URL)
.path("/{empcode}")
.resolveTemplate("empcode", 1002)
.request(MediaType.APPLICATION_XML)
.delete(String.class);
String result = PASS;
if(!SUCCESS.equals(callResult)){
result = FAIL;
}
System.out.println("Test case name: testDelete, Result: " + result );
}
}
</employee></list></list></pre>
<br />
<br />
<b><u>web.xml</u></b>
<br />
<?xml version="1.0" encoding="UTF-8"?><br/>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <br/>
xmlns="http://java.sun.com/xml/ns/javaee" <br/>
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee <br/>
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" <br/>
id="WebApp_ID" version="3.0"><br/>
<display-name>Employee Management</display-name><br/>
<servlet><br/>
<servlet-name>Jersey RESTful Application</servlet-name><br/>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class><br/>
<init-param><br/>
<param-name>jersey.config.server.provider.packages</param-name><br/>
<param-value>in.theinsanetechie.rest</param-value><br/>
</init-param><br/>
</servlet><br/>
<servlet-mapping><br/>
<servlet-name>Jersey RESTful Application</servlet-name><br/>
<url-pattern>/rest/*</url-pattern><br/>
</servlet-mapping> <br/>
</web-app><br/>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com1tag:blogger.com,1999:blog-1188765056128955958.post-37162178876859148362016-03-09T21:57:00.003+05:302020-11-01T10:25:28.205+05:30Installing and Configuring phpMyAdmin in Ubuntu/Linux Mint<br />
<b>Install phpmyadmin
</b><br />
<pre class="c" name="code">sudo apt-get install phpmyadmin
</pre>
<br />
<b>Configure phpmyadmin
</b><br />
<pre class="c" name="code">sudo dpkg-reconfigure -plow phpmyadmin
</pre>
<br />
Then select Apache 2 for the webserver you wish to configure.
<br />
<br />
Try hitting the URL <b>http://localhost/phpmyadmin/
</b><br />
<br />
If this does not work, then you have to include the phpMyAdmin-shipped Apache configuration into Apache:
<br />
<br />
<pre class="c" name="code">sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf.d/phpmyadmin.conf
sudo /etc/init.d/apache2 reload
</pre>
<br />
Since Ubuntu 13.10 (Saucy Salamander), Apache no longer loads configuration files from the /etc/apache2/conf.d directory.<br />
Instead, they are placed in the /etc/apache2/conf-available directory which is managed with the a2enconf command.<br />
Therefore, if you need to manually include the phpMyAdmin-shipped Apache configuration file, you must run the following:
<br />
<br />
<pre class="c" name="code">sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
sudo a2enconf phpmyadmin
sudo /etc/init.d/apache2 reload
</pre>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-55647207458382097982016-02-14T01:23:00.002+05:302020-11-01T10:25:47.422+05:30DNS Lookup - Implementation in C<br />
Read about DNS <a href="https://en.wikipedia.org/wiki/Domain_Name_System" target="_blank">here...</a><br />
<br />
<b><u>DNS Lookup - Implementation in C
</u></b><br />
<pre class="c" name="code">
/**dnsclient.c**/
#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include"netdb.h"
#include"arpa/inet.h"
#define BUF_SIZE 512
#define SERVER "8.8.8.8"
#define PORT 53
#define WIDTH 16
int createSocket();
void createRequest(char * url);
void hexdump (char *desc, void *addr, int len);
void lookUp();
struct query {
uint16_t length;
char * url;
unsigned char request[BUF_SIZE];
uint16_t reqType;
};
struct query dnsQuery = {
.length = 12,
.url = "",
.reqType = 0x01,
.request = { 0xDB, 0x42, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
int main(int argc, char** argv) {
char * url;
if (argc != 2) {
fprintf(stderr,"usage: %s hostnameToResolve\n", argv[0]);
exit(1);
}
url = argv[1];
createRequest(url);
lookUp();
}
int createSocket() {
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
//printf("Socket created...\n");
return sockfd;
}
void createRequest(char * url) {
char * word;
int i;
printf("Asking DNS server %s about %s\n", SERVER, url);
dnsQuery.url = strdup(url);
dnsQuery.reqType = 0x01;
word = strtok(url, ".");
while (word) {
printf("parsing hostname: \"%s\" is %d characters\n", word,
strlen(word));
dnsQuery.request[dnsQuery.length++] = strlen(word);
for (i = 0; i < strlen(word); i++) {
dnsQuery.request[dnsQuery.length++] = word[i];
}
word = strtok(NULL, ".");
}
dnsQuery.request[dnsQuery.length++] = 0x00; // End of the host name
dnsQuery.request[dnsQuery.length++] = 0x00; // 0x0001 - Query is a Type A
// query (host address)
dnsQuery.request[dnsQuery.length++] = dnsQuery.reqType;
dnsQuery.request[dnsQuery.length++] = 0x00; // 0x0001 - Query is class IN
// (Internet address)
dnsQuery.request[dnsQuery.length++] = 0x01;
}
// http://stackoverflow.com/questions/7775991/how-to-get-hexdump-of-a-structure-data
void hexdump (char *desc, void *addr, int len) {
int i;
unsigned char buff[17];
unsigned char *pc = addr;
// Output description if given.
if (desc != NULL)
printf ("%s:\n", desc);
// Process every byte in the data.
for (i = 0; i < len; i++) {
// Multiple of 16 means new line (with line offset).
if ((i % 16) == 0) {
// Just don't print ASCII for the zeroth line.
if (i != 0)
printf (" %s\n", buff);
// Output the offset.
printf (" %04x ", i);
}
// Now the hex code for the specific character.
printf (" %02x", pc[i]);
// And store a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e))
buff[i % 16] = '.';
else
buff[i % 16] = pc[i];
buff[(i % 16) + 1] = '\0';
}
// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) {
printf (" ");
i++;
}
// And print the final ASCII bit.
printf (" %s\n", buff);
}
void lookUp() {
struct sockaddr_in addr;
int socket;
int ret, rcode, size, i;
int ip = 0, dom = 0;
int length;
unsigned char buffer[BUF_SIZE];
unsigned char tempBuf[3];
uint16_t QDCOUNT; //No. of items in Question Section
uint16_t ANCOUNT; //No. of items in Answer Section
uint16_t NSCOUNT; //No. of items in Authority Section
uint16_t ARCOUNT; //No. of items in Additional Section
uint16_t QCLASS; //Specifies the class of the query
uint16_t ATYPE; //Specifies the meaning of the data in the RDATA field
uint16_t ACLASS; //Specifies the class of the data in the RDATA field
uint32_t TTL; //The number of seconds the results can be cached
uint16_t RDLENGTH; //The length of the RDATA field
uint16_t MSGID;
socket = createSocket();
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(SERVER);
addr.sin_port = htons(PORT);
size = sizeof(addr);
hexdump("sending packet", &dnsQuery.request, dnsQuery.length);
ret = sendto(socket, dnsQuery.request, dnsQuery.length, 0,
(struct sockaddr*)&addr, size);
if (ret < 0) {
printf("Error Sending Request");
exit(1);
}
//printf("Sent\n");
memset(&buffer, 0, BUF_SIZE);
ret = recvfrom(socket, buffer, BUF_SIZE, 0, (struct sockaddr*)&addr,
&size);
if (ret < 0) {
printf("Error Receiving Response");
exit(1);
}
hexdump("received packet", &buffer, ret);
close(socket);
rcode = (buffer[3] & 0x0F);
//tempBuf[0] = buffer[4];
//tempBuf[1] = buffer[5];
//tempBuf[2] = '\0';
//printf("%0x %0x %0x %0x\n", buffer[4], buffer[5], tempBuf[0], tempBuf[1]);
//QDCOUNT = (uint16_t) strtol(tempBuf, NULL, 16);
QDCOUNT = (uint16_t) buffer[4] * 0x100 + buffer[5];
printf("entries in question section: %u\n", QDCOUNT);
ANCOUNT = (uint16_t) buffer[6] * 0x100 + buffer[7];
printf("records in answer section: %u\n", ANCOUNT);
NSCOUNT = (uint16_t) buffer[8] * 0x100 + buffer[9];
printf("name server resource record count: %u\n", NSCOUNT);
ARCOUNT = (uint16_t) buffer[10] * 0x100 + buffer[11];
printf("additional records count: %u\n", ARCOUNT);
printf("query type: %u\n", dnsQuery.reqType);
QCLASS = (uint16_t) dnsQuery.request[dnsQuery.length - 2] * 0x100 +
dnsQuery.request[dnsQuery.length - 1];
printf("query class: %u\n", QCLASS);
length = dnsQuery.length + 1; // to skip 0xc00c
ATYPE = (uint16_t) buffer[length + 1] * 0x100 + buffer[length + 2];
printf("answer type: %u\n", ATYPE);
ACLASS = (uint16_t) buffer[length + 3] * 0x100 + buffer[length + 4];
printf("answer class: %u\n", ACLASS);
TTL = (uint32_t) buffer[length + 5] * 0x1000000 + buffer[length + 6] *
0x10000 + buffer[length + 7] * 0x100 + buffer[length + 8];
printf("seconds to cache: %u\n", TTL);
RDLENGTH = (uint16_t) buffer[length + 9] * 0x100 + buffer[length + 10];
printf("bytes in answer: %u\n", RDLENGTH);
MSGID = (uint16_t) buffer[0] * 0x100 + buffer[1];
printf("answer msg id: %u\n", MSGID);
if (rcode == 2) {
printf("nameserver %s returned SERVFAIL:\n", SERVER);
printf(" the name server was unable to process this query due to"
+ " a\n problem with the name server.\n");
exit(1);
} else if (rcode == 3) {
printf("nameserver %s returned NXDOMAIN for %s:\n", SERVER,
dnsQuery.url);
printf(" the domain name referenced in the query does not exist\n");
exit(1);
}
/* search for and print IPv4 addresses */
if (dnsQuery.reqType == 0x01) {
printf("DNS server's answer is: (type#=%u):", ATYPE);
//printf("IPv4 address(es) for %s:\n", dnsQuery.url);
for (i = 0 ; i < ret ; i++) {
if (buffer[i] == 0xC0 && buffer[i+3] == 0x01) {
ip++; i += 12; /* ! += buf[i+1]; */
printf(" %u.%u.%u.%u\n", buffer[i], buffer[i+1],
buffer[i+2], buffer[i+3]);
}
}
if (!ip) {
printf(" No IPv4 address found in the DNS response!\n");
exit(1);
}
}
}
</pre>
<br />
<b><u>Output
</u></b><br />
<b><u><br /></u></b>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/_works$ gcc dnsclient.c </span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/_works$ ./a.out www.theinsanetechie.in</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Asking DNS server 8.8.8.8 about www.theinsanetechie.in</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">parsing hostname: "www" is 3 characters</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">parsing hostname: "theinsanetechie" is 15 characters</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">parsing hostname: "in" is 2 characters</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">sending packet:</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0000 db 42 01 00 00 01 00 00 00 00 00 00 03 77 77 77 .B...........www</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0010 0f 74 68 65 69 6e 73 61 6e 65 74 65 63 68 69 65 .theinsanetechie</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0020 02 69 6e 00 00 01 00 01 .in.....</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">received packet:</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0000 db 42 81 80 00 01 00 03 00 00 00 00 03 77 77 77 .B...........www</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0010 0f 74 68 65 69 6e 73 61 6e 65 74 65 63 68 69 65 .theinsanetechie</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0020 02 69 6e 00 00 01 00 01 c0 0c 00 05 00 01 00 00 .in.............</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0030 32 c7 00 10 03 67 68 73 06 67 6f 6f 67 6c 65 03 2....ghs.google.</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0040 63 6f 6d 00 c0 34 00 05 00 01 00 00 54 5f 00 08 com..4......T_..</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0050 03 67 68 73 01 6c c0 38 c0 50 00 01 00 01 00 00 .ghs.l.8.P......</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 0060 01 2b 00 04 4a 7d 44 79 .+..J}Dy</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">entries in question section: 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">records in answer section: 3</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">name server resource record count: 0</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">additional records count: 0</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">query type: 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">query class: 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">answer type: 5</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">answer class: 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">seconds to cache: 12999</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">bytes in answer: 16</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">answer msg id: 56130</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">DNS server's answer is: (type#=5): 74.125.68.121</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/_works$ </span><br />
<div>
<br /></div>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-11695262878869957902015-03-11T11:04:00.000+05:302015-03-11T11:04:01.199+05:30Java program to find the distance between two GPS locations.<b>Location.java</b>
<br />
<pre class="java" name="code">
package com.cables.gps;
public class Location {
private int latDegree;
private int latMinutes;
private int latSeconds;
private char latDirection;
private int longDegree;
private int longMinutes;
private int longSeconds;
private char longDirection;
private float latitude;
private float longitude;
private void init() throws Exception {
latitude = latDegree + (latMinutes / 60.0f) + (latSeconds / 3600.0f);
if (latDirection == 'N') {
latitude *= 1f;
} else if (latDirection == 'S'){
latitude *= -1f;
} else {
throw new Exception("Invalid Latitude Direction: " + latDirection);
}
longitude = longDegree + (longMinutes / 60.0f) + (longSeconds / 3600.0f);
if (longDirection == 'E') {
longitude *= 1f;
} else if (longDirection == 'W') {
longitude *= -1f;
} else {
throw new Exception("Invalid Longitude Direction: " + longDirection);
}
}
public String toString() {
String returnString = "";
try {
init();
} catch (Exception e) {
e.printStackTrace();
return null;
}
returnString += "(" + latitude + ", " + longitude + ")";
return returnString;
}
public void setLatitude(int deg, int min, int sec, char dir) {
latDegree = deg;
latMinutes = min;
latSeconds = sec;
latDirection = dir;
}
public void setLongitude(int deg, int min, int sec, char dir) {
longDegree = deg;
longMinutes = min;
longSeconds = sec;
longDirection = dir;
}
public int getLatDegree() {
return latDegree;
}
public void setLatDegree(int latDegree) {
this.latDegree = latDegree;
}
public int getLatMinutes() {
return latMinutes;
}
public void setLatMinutes(int latMinutes) {
this.latMinutes = latMinutes;
}
public int getLatSeconds() {
return latSeconds;
}
public void setLatSeconds(int latSeconds) {
this.latSeconds = latSeconds;
}
public char getLatDirection() {
return latDirection;
}
public void setLatDirection(char latDirection) throws Exception {
if (latDirection != 'N' && latDirection != 'S') {
throw new Exception("Invalid Latitude Direction: " + latDirection);
}
this.latDirection = latDirection;
}
public int getLongDegree() {
return longDegree;
}
public void setLongDegree(int longDegree) {
this.longDegree = longDegree;
}
public int getLongMinutes() {
return longMinutes;
}
public void setLongMinutes(int longMinutes) {
this.longMinutes = longMinutes;
}
public int getLongSeconds() {
return longSeconds;
}
public void setLongSeconds(int longSeconds) {
this.longSeconds = longSeconds;
}
public char getLongDirection() {
return longDirection;
}
public void setLongDirection(char longDirection) throws Exception {
if (longDirection != 'E' && longDirection != 'W') {
throw new Exception("Invalid Longitude Direction: " + longDirection);
}
this.longDirection = longDirection;
}
public float getLatitude() throws Exception {
init();
return latitude;
}
public void setLatitude(float latitude) {
this.latitude = latitude;
}
public float getLongitude() throws Exception {
init();
return longitude;
}
public void setLongitude(float longitude) {
this.longitude = longitude;
}
public void setLatString(String latStr) throws Exception {
latStr = latStr.trim();
String[] values = latStr.split(" ");
latDegree = Integer.parseInt(values[0].trim());
latMinutes = Integer.parseInt(values[1].trim());
latSeconds = Integer.parseInt(values[2].trim());
latDirection = values[3].trim().charAt(0);
if (latDirection != 'N' && latDirection != 'S') {
throw new Exception("Invalid Latitude Direction: " + latDirection);
}
}
public void setLongString(String longStr) throws Exception {
longStr = longStr.trim();
String[] values = longStr.split(" ");
longDegree = Integer.parseInt(values[0].trim());
longMinutes = Integer.parseInt(values[1].trim());
longSeconds = Integer.parseInt(values[2].trim());
longDirection = values[3].trim().charAt(0);
if (longDirection != 'E' && longDirection != 'W') {
throw new Exception("Invalid Longitude Direction: " + longDirection);
}
}
}
</pre>
<b>LocationOps.java</b>
<pre class="java" name="code">
package com.cables.gps;
public class LocationOps {
private Location location1 = null;
private Location location2 = null;
private int radius = 6371;
public LocationOps(Location location1, Location location2) {
this.location1 = location1;
this.location2 = location2;
}
public double calculateDistance() throws Exception {
double distance = 0.0;
double lat1 = degreesToRadians(location1.getLatitude());
double lat2 = degreesToRadians(location2.getLatitude());
double dLat = degreesToRadians(
location2.getLatitude() - location1.getLatitude());
double dLong = degreesToRadians(
location2.getLongitude() - location1.getLongitude());
double a = Math.sin(dLat/2.0) * Math.sin(dLat/2.0)
+ Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLong/2.0) * Math.sin(dLong/2.0);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
distance = radius * c;
return distance;
}
public double degreesToRadians(double degrees) {
double radians = 0.0;
radians = degrees * Math.PI / 180.0;
return radians;
}
public static void main(String[] args) throws Exception {
Location loc1 = new Location();
loc1.setLatDegree(50);
loc1.setLatMinutes(03);
loc1.setLatSeconds(59);
loc1.setLatDirection('N');
loc1.setLongDegree(005);
loc1.setLongMinutes(42);
loc1.setLongSeconds(53);
loc1.setLongDirection('W');
Location loc2 = new Location();
loc2.setLatDegree(58);
loc2.setLatMinutes(38);
loc2.setLatSeconds(38);
loc2.setLatDirection('N');
loc2.setLongDegree(003);
loc2.setLongMinutes(04);
loc2.setLongSeconds(12);
loc2.setLongDirection('W');
System.out.println(new LocationOps(loc1, loc2).calculateDistance());
loc1.setLatString("50 03 59 N");
loc1.setLongString("005 42 53 W");
loc2.setLatString("58 38 38 N");
loc2.setLongString("003 04 12 W");
System.out.println(new LocationOps(loc1, loc2).calculateDistance());
}
}
</pre>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-40208283543107372092014-12-30T09:36:00.002+05:302014-12-30T09:37:58.406+05:30Sum of Prime Numbers Between 1000000 and 1000100 Using Sieve of EratosthenesNB: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes<br />
<br />
<pre class="c" name="code">
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "assert.h"
typedef unsigned long long biggerint;
void findPrimeNumbers(biggerint start, biggerint end) {
char * primeList = malloc(sizeof(unsigned char) * (end + 1));
int i;
biggerint sum = 0;
assert(primeList != NULL);
/* set prime status */
for (i = 0; i <= end + 1 ; i++) {
*(primeList + i) = 1;
}
primeList[0] = 0;
primeList[1] = 0;
/* mark all the non-prime numbers */
biggerint currentFactor = 2;
biggerint lastSquare = 0;
biggerint currentSquare = 0;
while (currentFactor * currentFactor <= end) {
/* mark all the multiples of the current factor */
biggerint mark = currentFactor + currentFactor;
while (mark <= end) {
*(primeList + mark) = 0;
mark += currentFactor;
}
/* set currentFactor to next prime number */
currentFactor++;
while (*(primeList+currentFactor) == 0) currentFactor++;
assert(currentFactor <= end);
}
for(i = start; i <= end ; i++) {
if(*(primeList + i)) sum += i;
}
free(primeList);
printf("%llu\n", sum);
}
int main(int argc, char *argv[]) {
biggerint start = 1000000;
biggerint end = 1000100;
findPrimeNumbers(start, end);
return 0;
}
</pre>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-53269889120873148002014-07-30T23:19:00.000+05:302014-07-30T23:19:15.703+05:30AES Implementation In Java with ECB | CBC | OFB | CFB Modes Of Operation<b><i>Note that these are ONLY basic level programs for easy understanding of the Advanced Encryption Standard (AES) algorithm</i></b><br />
<br />
<b>Key Generation - AESkeygen.java</b>
<br />
<pre class="java" name="code">
import java.io.File;
import java.io.FileWriter;
public class AESkeygen {
private final File file = new File("AESkey.txt");
private final int KEY_LENGTH = 32;
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public AESkeygen() {
try {
FileWriter fileWriter = new FileWriter(file);
fileWriter.write("");
for (int i = 0 ; i < KEY_LENGTH ; i++) {
double random = Math.random();
int index = (int) (random * 16);
fileWriter.append(hexArray[index]);
fileWriter.flush();
}
fileWriter.close();
System.out.println("Key generated and saved in " + file.getName());
} catch(Exception exp) {
exp.printStackTrace();
}
}
public static void main(String[] args) {
new AESkeygen();
}
}
</pre>
<br />
<b>Word.java</b>
<br />
<pre class="java" name="code">
public class Word {
private byte[] word = null;
public Word() {
word = new byte[4];
}
public Word(byte k0, byte k1, byte k2, byte k3) {
this();
word[0] = k0;
word[1] = k1;
word[2] = k2;
word[3] = k3;
}
public byte[] getWord() {
return word;
}
public void setWord(byte[] word) {
this.word = word;
}
public static byte[] wordToBytes(Word word) {
return word.getWord();
}
public static byte[] wordsToBytes(Word[] words) {
byte[] out = new byte[4 * words.length];
for (int i = 0 ; i < words.length ; i++) {
byte[] temp = words[i].getWord();
out[4*i] = temp[0];
out[4*i+1] = temp[1];
out[4*i+2] = temp[2];
out[4*i+3] = temp[3];
}
return out;
}
public void rotWord() {
byte[] temp = this.getWord();
byte[] newWord = new byte[4];
newWord[0] = temp[1];
newWord[1] = temp[2];
newWord[2] = temp[3];
newWord[3] = temp[0];
this.setWord(newWord);
}
public void subWord() {
byte[] in = this.getWord();
byte[] out = new byte[4];
for (int i = 0 ; i < 4 ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) AESencrypt.sBox[row * 16 + col];
}
for (int i = 0 ; i < 4 ; i++) {
this.word[i] = out[i];
}
}
public static Word XORWords(Word word1, Word word2) {
Word outWord = new Word();
byte[] in1 = word1.getWord();
byte[] in2 = word2.getWord();
byte[] out = new byte[4];
for (int i = 0 ; i < 4 ; i++) {
out[i] = (byte)((in1[i] ^ in2[i]) & 0xff);
}
outWord.setWord(out);
return outWord;
}
public String toString() {
return AESencrypt.bytesToHex(this.getWord());
}
}
</pre>
<br />
<b>Encryption - AESencrypt.java</b>
<br />
<pre class="java" name="code">
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.Arrays;
public class AESencrypt {
private static final int BITS = 16;
private static final int ROUNDS = 10;
private static final int NO_OF_WORDS_IN_KEY = 44;
private static final int KEY_LENGTH = 16;
private static final int BLOCK_LENGTH = 16;
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
int[] RC = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36};
Word[] Rcon = new Word[ROUNDS];
private byte[] word = null;
private String mode = null;
static final int[] sBox = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static final int[] invSBox = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
public AESencrypt(String mode) {
this.mode = mode;
for (int i = 0 ; i < ROUNDS ; i++) {
Rcon[i] = new Word();
byte[] temp = new byte[4];
temp[0] = (byte) (RC[i] & 0xff);
temp[1] = 0;
temp[2] = 0;
temp[3] = 0;
Rcon[i].setWord(temp);
}
word = new byte[NO_OF_WORDS_IN_KEY];
}
/* Ref: http://www.samiam.org/galois.html */
/* Galois Addition*/
byte gadd(byte a, byte b) {
return (byte) ((a ^ b) & 0xff);
}
/* Galois Subtraction*/
byte gsub(byte a, byte b) {
return (byte) ((a ^ b) & 0xff);
}
/* Galois Multiplication*/
byte gmul(byte a, byte b) {
byte p = 0;
int counter;
byte high_bit_set;
byte byte0x80 = hexStringToByteArray("80")[0];
for (counter = 0 ; counter < 8 ; counter++) {
if((b & 0x01) == 1) {
//System.out.println("lower bit of b is set");
p = (byte)((p ^ a) & 0xff);
}
high_bit_set = (byte) (a & 0x80);
//printByte("high_bit_set", high_bit_set);
a <<= 1;
if (high_bit_set == byte0x80) {
//System.out.println("higher bit of a is set");
a = (byte)((a ^ 0x1b) & 0xff);
}
b = (byte)((b >> 1) & 0x7f);
//printByte("a", a);
//printByte("b", b);
//printByte("p", p);
}
return p;
}
byte gmul(byte a, int b) {
byte t = (byte)(b & 0xff);
return gmul(a, t);
}
/* Key Expansion */
private byte[] expandKey(byte[] key) throws Exception {
//System.out.println(key.length);
//System.out.println(bytesToHex(key));
if(key.length != KEY_LENGTH) {
throw new Exception("Key should be of length, 128 bits");
}
Word[] w = new Word[NO_OF_WORDS_IN_KEY];
Word temp;
for (int i = 0; i < 4; i++) {
w[i] = new Word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]);
//System.out.println("w" + i + " = " + w[i]);
}
for (int i = 4; i < 44; i++) {
temp = w[i-1];
Word temp1 = new Word();
temp1.setWord(temp.getWord());
//System.out.println("w" + (i-1) + " = " + temp);
if (i % 4 == 0) {
temp1.rotWord();
//System.out.println("Rot=" + temp1);
temp1.subWord();
//System.out.println("Sub=" + temp1);
temp1 = Word.XORWords(temp1, Rcon[(i/4) - 1]);
//System.out.println("Rcon" + temp1);
}
w[i] = Word.XORWords(w[i-4], temp1);
//System.out.println("w" + i + " = " + w[i]);
}
return Word.wordsToBytes(w);
}
/* Substitute Bytes */
private byte[] subBytes(byte[] in) {
byte[] out = new byte[BITS];
for (int i = 0 ; i < BITS ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) sBox[row * BITS + col];
}
return out;
}
/* Inverse Substitute Bytes */
private byte[] inverseSubBytes(byte[] in) {
byte[] out = new byte[BITS];
for (int i = 0 ; i < BITS ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) invSBox[row * BITS + col];
}
return out;
}
/* Shift Rows */
private byte[] shiftRows(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
//System.out.println("temp: " + bytesToHex(temp));
for (int i = 0 ; i < BITS/4 ; i++) {
byte[] a = Arrays.copyOfRange(temp, (4 * i), (4 * i + 4));
byte[] b = leftShift(a, i);
in[4*i] = b[0];
in[4*i+1] = b[1];
in[4*i+2] = b[2];
in[4*i+3] = b[3];
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*j+i] = in[4*i+j];
}
}
return out;
}
private byte[] leftShift(byte[] in, int times) {
byte[] out = new byte[4];
out = Arrays.copyOfRange(in, 0, 4);
for (int i = 0 ; i < times ; i++) {
out[0] = in[1];
out[1] = in[2];
out[2] = in[3];
out[3] = in[0];
in = Arrays.copyOfRange(out, 0, 4);
}
return out;
}
/* Inverse Shift Rows */
private byte[] inverseShiftRows(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
for (int i = 0 ; i < BITS/4 ; i++) {
byte[] a = Arrays.copyOfRange(temp, (4 * i), (4 * i + 4));
byte[] b = rightShift(a, i);
in[4 * i] = b[0];
in[4 * i + 1] = b[1];
in[4 * i + 2] = b[2];
in[4 * i + 3] = b[3];
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*j+i] = in[4*i+j];
}
}
return out;
}
private byte[] rightShift(byte[] in, int times) {
byte[] out = new byte[4];
out = Arrays.copyOfRange(in, 0, 4);
for (int i = 0 ; i < times ; i++) {
out[0] = in[3];
out[1] = in[0];
out[2] = in[1];
out[3] = in[2];
in = Arrays.copyOfRange(out, 0, 4);
}
return out;
}
/* Mix Columns */
private byte[] mixColumns(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
in = temp;
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*0+j] = (byte) ((gmul(in[4*0+j], 2) ^ gmul(in[4*1+j], 3) ^ in[4*2+j] ^ in[4*3+j]) & 0xff);
out[4*1+j] = (byte) ((in[4*0+j] ^ gmul(in[4*1+j], 2) ^ gmul(in[4*2+j], 3) ^ in[4*3+j]) & 0xff);
out[4*2+j] = (byte) ((in[4*0+j] ^ in[4*1+j] ^ gmul(in[4*2+j], 2) ^ gmul(in[4*3+j], 3)) & 0xff);
out[4*3+j] = (byte) ((gmul(in[4*0+j], 3) ^ in[4*1+j] ^ in[4*2+j] ^ gmul(in[4*3+j], 2)) & 0xff);
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = out[4*i+j];
}
}
out = temp;
return out;
}
/* Inverse Mix Columns */
private byte[] inverseMixColumns(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
in = temp;
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*0+j] = (byte) ((gmul(in[4*0+j], 14) ^ gmul(in[4*1+j], 11) ^ gmul(in[4*2+j], 13) ^ gmul(in[4*3+j], 9)) & 0xff);
out[4*1+j] = (byte) ((gmul(in[4*0+j], 9) ^ gmul(in[4*1+j], 14) ^ gmul(in[4*2+j], 11) ^ gmul(in[4*3+j], 13)) & 0xff);
out[4*2+j] = (byte) ((gmul(in[4*0+j], 13) ^ gmul(in[4*1+j], 9) ^ gmul(in[4*2+j], 14) ^ gmul(in[4*3+j], 11)) & 0xff);
out[4*3+j] = (byte) ((gmul(in[4*0+j], 11) ^ gmul(in[4*1+j], 13) ^ gmul(in[4*2+j], 9) ^ gmul(in[4*3+j], 14)) & 0xff);
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = out[4*i+j];
}
}
out = temp;
return out;
}
private byte[] hexStringToByteArray(String string) {
int length = string.length();
int n = (int)Math.ceil((length + 1) / 2);
byte[] result = new byte[n];
for (int i = length - 1; i >= 0 ; i -= 2) {
if (i == 0) {
result[i / 2] = (byte) ((Character.digit('0', 16) << 4)
+ Character.digit(string.charAt(i), 16));
} else {
result[i / 2] = (byte) ((Character.digit(string.charAt(i - 1), 16) << 4)
+ Character.digit(string.charAt(i), 16));
}
}
return result;
}
/* http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java */
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private void printBytes(byte[] input) {
for (int i = 0 ; i < input.length; i++) {
System.out.print(byteToBits(input[i]) + " ");
}
System.out.println();
}
private void printByte(String msg, byte input) {
byte[] temp = new byte[1];
temp[0] = input;
System.out.println(msg + ": " + bytesToHex(temp));
}
private String byteToBits(byte b) {
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 8 ; i++)
buffer.append((int)(b >> (8-(i+1)) & 0x0001));
return buffer.toString();
}
private byte[] getRoundKey(int round) {
byte[] out = new byte[KEY_LENGTH];
out = Arrays.copyOfRange(word, 16*round, 16*round+16);
return out;
}
public static byte[] XORBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length];
for (int i = 0 ; i < in1.length ; i++) {
out[i] = (byte)((in1[i] ^ in2[i]) & 0xff);
}
return out;
}
public byte[] encryptText(byte[] plainText, byte[] key) throws Exception {
byte[] cipher = new byte[BLOCK_LENGTH];
this.word = expandKey(key);
byte[] roundKey = getRoundKey(0);
/* Round 0 */
cipher = XORBytes(plainText, roundKey);
//System.out.println("Round 0\n" + bytesToHex(cipher));
/* Rounds 1 to 9*/
for (int i = 1 ; i < 10 ; i++) {
//System.out.println("Round " + i);
cipher = subBytes(cipher);
//System.out.println("SubBytes: " + bytesToHex(cipher));
cipher = shiftRows(cipher);
//System.out.println("ShiftRows: " + bytesToHex(cipher));
cipher = mixColumns(cipher);
//System.out.println("MixColumns: " + bytesToHex(cipher));
roundKey = getRoundKey(i);
//System.out.println("RoundKey: " + bytesToHex(roundKey));
cipher = XORBytes(cipher, roundKey);
//System.out.println("CIPHER: " + bytesToHex(cipher));
}
/* Round 10*/
//System.out.println("Round 10");
cipher = subBytes(cipher);
//System.out.println("SubBytes: " + bytesToHex(cipher));
cipher = shiftRows(cipher);
//System.out.println("ShiftRows: " + bytesToHex(cipher));
roundKey = getRoundKey(10);
//System.out.println("RoundKey: " + bytesToHex(roundKey));
cipher = XORBytes(cipher, roundKey);
//System.out.println("CIPHER: " + bytesToHex(cipher));
return cipher;
}
public byte[] decryptText(byte[] cipher, byte[] key) throws Exception {
byte[] plainText = new byte[BLOCK_LENGTH];
this.word = expandKey(key);
byte[] roundKey = getRoundKey(10);
/* Round 0 */
plainText = XORBytes(cipher, roundKey);
/* Rounds 1 to 9*/
for (int i = 9 ; i > 0 ; i--) {
plainText = inverseShiftRows(plainText);
plainText = inverseSubBytes(plainText);
roundKey = getRoundKey(i);
plainText = XORBytes(plainText, roundKey);
plainText = inverseMixColumns(plainText);
}
/* Round 10*/
plainText = inverseShiftRows(plainText);
plainText = inverseSubBytes(plainText);
roundKey = getRoundKey(0);
plainText = XORBytes(plainText, roundKey);
return plainText;
}
public static void main(String[] args) throws Exception {
try {
if (args.length != 1) {
System.out.println("Usage: java < classname > < mode >"
+ "\n\t< mode > := (ECB|CBC|OFB|CFB)");
return;
}
/* ECB, CBC, OFB, or CFB */
String mode = args[0];
//String mode = "CFB";
mode = mode.toUpperCase();
AESencrypt aes = new AESencrypt(mode);
File keyFile = new File("AESkey.txt");
File textFile = new File("AESplaintext.txt");
File cipherFile = new File("AESciphertext.txt");
FileReader keyFileReader = new FileReader(keyFile);
BufferedReader bufferedReader = new BufferedReader(keyFileReader);
FileInputStream textFileInputStream = new FileInputStream(textFile);
FileOutputStream cipherFileOutputStream = new FileOutputStream(cipherFile);
byte[] key = new byte[(int) keyFile.length()];
String keyString = bufferedReader.readLine();
key = aes.hexStringToByteArray(keyString);
byte[] message = new byte[(int) textFile.length()];
textFileInputStream.read(message);
byte[] cipher = aes.encrypt(message, key);
cipherFileOutputStream.write(cipher);
cipherFileOutputStream.flush();
cipherFileOutputStream.close();
bufferedReader.close();
textFileInputStream.close();
System.out.println("Encryption done! Please check AESciphertext.txt for output!");
} catch(Exception exp) {
exp.printStackTrace();
}
}
private byte[] encrypt(byte[] message, byte[] key) throws Exception {
if (message.length < 16) {
System.out.println("Message should be atleast 64 bits");
System.exit(1);
}
if (key.length != 16) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
int length = message.length;
int n = (length + 15)/16 * 16;
byte[] cipher = new byte[n];
if (length == 16) {
if (mode.equals("ECB")) {
return encryptText(message, key);
} else if (mode.equals("CBC")) {
byte[] iv = getInitializationVector();
message = XORBytes(message, iv);
return encryptText(message, key);
} else if (mode.equals("OFB")) {
byte[] nounce = getNounce();
byte[] temp = encryptText(nounce, key);
byte[] result = XORBytes(temp, message);
return result;
} else if (mode.equals("CFB")) {
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
}
int i = 0;
int k = 0;
byte[] feedback = new byte[16];
if (mode.equals("CBC")) {
feedback = getInitializationVector();
} else if (mode.equals("OFB")) {
feedback = getNounce();
} else if (mode.equals("CFB")) {
feedback = getInitializationVectorCFB();
}
while (i < length) {
byte[] block = new byte[16];
byte[] result = new byte[16];
int j = 0;
for (; j < 16 && i < length; j++, i++) {
block[j] = message[i];
}
while (j < 16) {
/* pad with white spaces */
block[j++] = 0x20;
}
//System.out.println("BLOCK: ");
//printBytes(block);
if (mode.equals("ECB")) {
result = encryptText(block, key);
} else if (mode.equals("CBC")) {
block = XORBytes(block, feedback);
result = encryptText(block, key);
feedback = Arrays.copyOfRange(result, 0, 16);
} else if (mode.equals("OFB")) {
result = encryptText(feedback, key);
feedback = Arrays.copyOfRange(result, 0, 16);
result = XORBytes(result, block);
} else if (mode.equals("CFB")) {
result = encryptText(feedback, key);
byte[] resultPart = Arrays.copyOfRange(result, 0, 8);
byte[] blockPart = Arrays.copyOfRange(block, 0, 8);
byte[] temp1 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 8, 16), temp1);
resultPart = Arrays.copyOfRange(result, 8, 16);
blockPart = Arrays.copyOfRange(block, 8, 16);
result = encryptText(feedback, key);
byte[] temp2 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 8, 16), temp2);
result = mergeBytes(temp1, temp2);
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
//System.out.println("RESULT: ");
//printBytes(result);
for (j = 0 ; j < 16 && k < cipher.length; j++, k++) {
cipher[k] = result[j];
}
}
return cipher;
}
private byte[] getInitializationVector() {
return hexStringToByteArray("247D8AC4DDB1AA739DC593821D0BC432");
}
private byte[] getInitializationVectorCFB() {
return hexStringToByteArray("247D8AC4DDB1AA739DC593821D0BC432");
}
private byte[] getNounce() {
// char[] hexArray = "0123456789ABCDEF".toCharArray();
// String nounceStr = "";
// for (int i = 0 ; i < 16 ; i++) {
// double random = Math.random();
// int index = (int) (random * 16);
// nounceStr += hexArray[index];
// }
// return hexStringToByteArray(nounceStr);
return hexStringToByteArray("247D8AC4DDB1AA739DC593821D0BC432");
}
private byte[] mergeBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length + in2.length];
int i = 0;
for (int j = 0 ; j < in1.length ; j++) {
out[i++] = in1[j];
}
for (int j = 0 ; j < in2.length ; j++) {
out[i++] = in2[j];
}
return out;
}
}
</pre>
<br />
<b>Decryption - AESdecrypt.java</b>
<br />
<pre class="java" name="code">
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.Arrays;
public class AESdecrypt {
private static final int BITS = 16;
private static final int ROUNDS = 10;
private static final int NO_OF_WORDS_IN_KEY = 44;
private static final int KEY_LENGTH = 16;
private static final int BLOCK_LENGTH = 16;
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
int[] RC = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36};
Word[] Rcon = new Word[ROUNDS];
private byte[] word = null;
private String mode = null;
static final int[] sBox = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static final int[] invSBox = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
public AESdecrypt(String mode) {
this.mode = mode;
for (int i = 0 ; i < ROUNDS ; i++) {
Rcon[i] = new Word();
byte[] temp = new byte[4];
temp[0] = (byte) (RC[i] & 0xff);
temp[1] = 0;
temp[2] = 0;
temp[3] = 0;
Rcon[i].setWord(temp);
}
word = new byte[NO_OF_WORDS_IN_KEY];
}
/* Ref: http://www.samiam.org/galois.html */
/* Galois Addition*/
byte gadd(byte a, byte b) {
return (byte) ((a ^ b) & 0xff);
}
/* Galois Subtraction*/
byte gsub(byte a, byte b) {
return (byte) ((a ^ b) & 0xff);
}
/* Galois Multiplication*/
byte gmul(byte a, byte b) {
byte p = 0;
int counter;
byte high_bit_set;
byte byte0x80 = hexStringToByteArray("80")[0];
for (counter = 0 ; counter < 8 ; counter++) {
if((b & 0x01) == 1) {
//System.out.println("lower bit of b is set");
p = (byte)((p ^ a) & 0xff);
}
high_bit_set = (byte) (a & 0x80);
//printByte("high_bit_set", high_bit_set);
a <<= 1;
if (high_bit_set == byte0x80) {
//System.out.println("higher bit of a is set");
a = (byte)((a ^ 0x1b) & 0xff);
}
b = (byte)((b >> 1) & 0x7f);
//printByte("a", a);
//printByte("b", b);
//printByte("p", p);
}
return p;
}
byte gmul(byte a, int b) {
byte t = (byte)(b & 0xff);
return gmul(a, t);
}
/* Key Expansion */
private byte[] expandKey(byte[] key) throws Exception {
//System.out.println(key.length);
//System.out.println(bytesToHex(key));
if(key.length != KEY_LENGTH) {
throw new Exception("Key should be of length, 128 bits");
}
Word[] w = new Word[NO_OF_WORDS_IN_KEY];
Word temp;
for (int i = 0; i < 4; i++) {
w[i] = new Word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]);
//System.out.println("w" + i + " = " + w[i]);
}
for (int i = 4; i < 44; i++) {
temp = w[i-1];
Word temp1 = new Word();
temp1.setWord(temp.getWord());
//System.out.println("w" + (i-1) + " = " + temp);
if (i % 4 == 0) {
temp1.rotWord();
//System.out.println("Rot=" + temp1);
temp1.subWord();
//System.out.println("Sub=" + temp1);
temp1 = Word.XORWords(temp1, Rcon[(i/4) - 1]);
//System.out.println("Rcon" + temp1);
}
w[i] = Word.XORWords(w[i-4], temp1);
//System.out.println("w" + i + " = " + w[i]);
}
return Word.wordsToBytes(w);
}
/* Substitute Bytes */
private byte[] subBytes(byte[] in) {
byte[] out = new byte[BITS];
for (int i = 0 ; i < BITS ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) sBox[row * BITS + col];
}
return out;
}
/* Inverse Substitute Bytes */
private byte[] inverseSubBytes(byte[] in) {
byte[] out = new byte[BITS];
for (int i = 0 ; i < BITS ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) invSBox[row * BITS + col];
}
return out;
}
/* Shift Rows */
private byte[] shiftRows(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
//System.out.println("temp: " + bytesToHex(temp));
for (int i = 0 ; i < BITS/4 ; i++) {
byte[] a = Arrays.copyOfRange(temp, (4 * i), (4 * i + 4));
byte[] b = leftShift(a, i);
in[4*i] = b[0];
in[4*i+1] = b[1];
in[4*i+2] = b[2];
in[4*i+3] = b[3];
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*j+i] = in[4*i+j];
}
}
return out;
}
private byte[] leftShift(byte[] in, int times) {
byte[] out = new byte[4];
out = Arrays.copyOfRange(in, 0, 4);
for (int i = 0 ; i < times ; i++) {
out[0] = in[1];
out[1] = in[2];
out[2] = in[3];
out[3] = in[0];
in = Arrays.copyOfRange(out, 0, 4);
}
return out;
}
/* Inverse Shift Rows */
private byte[] inverseShiftRows(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
for (int i = 0 ; i < BITS/4 ; i++) {
byte[] a = Arrays.copyOfRange(temp, (4 * i), (4 * i + 4));
byte[] b = rightShift(a, i);
in[4 * i] = b[0];
in[4 * i + 1] = b[1];
in[4 * i + 2] = b[2];
in[4 * i + 3] = b[3];
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*j+i] = in[4*i+j];
}
}
return out;
}
private byte[] rightShift(byte[] in, int times) {
byte[] out = new byte[4];
out = Arrays.copyOfRange(in, 0, 4);
for (int i = 0 ; i < times ; i++) {
out[0] = in[3];
out[1] = in[0];
out[2] = in[1];
out[3] = in[2];
in = Arrays.copyOfRange(out, 0, 4);
}
return out;
}
/* Mix Columns */
private byte[] mixColumns(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
in = temp;
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*0+j] = (byte) ((gmul(in[4*0+j], 2) ^ gmul(in[4*1+j], 3) ^ in[4*2+j] ^ in[4*3+j]) & 0xff);
out[4*1+j] = (byte) ((in[4*0+j] ^ gmul(in[4*1+j], 2) ^ gmul(in[4*2+j], 3) ^ in[4*3+j]) & 0xff);
out[4*2+j] = (byte) ((in[4*0+j] ^ in[4*1+j] ^ gmul(in[4*2+j], 2) ^ gmul(in[4*3+j], 3)) & 0xff);
out[4*3+j] = (byte) ((gmul(in[4*0+j], 3) ^ in[4*1+j] ^ in[4*2+j] ^ gmul(in[4*3+j], 2)) & 0xff);
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = out[4*i+j];
}
}
out = temp;
return out;
}
/* Inverse Mix Columns */
private byte[] inverseMixColumns(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
in = temp;
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*0+j] = (byte) ((gmul(in[4*0+j], 14) ^ gmul(in[4*1+j], 11) ^ gmul(in[4*2+j], 13) ^ gmul(in[4*3+j], 9)) & 0xff);
out[4*1+j] = (byte) ((gmul(in[4*0+j], 9) ^ gmul(in[4*1+j], 14) ^ gmul(in[4*2+j], 11) ^ gmul(in[4*3+j], 13)) & 0xff);
out[4*2+j] = (byte) ((gmul(in[4*0+j], 13) ^ gmul(in[4*1+j], 9) ^ gmul(in[4*2+j], 14) ^ gmul(in[4*3+j], 11)) & 0xff);
out[4*3+j] = (byte) ((gmul(in[4*0+j], 11) ^ gmul(in[4*1+j], 13) ^ gmul(in[4*2+j], 9) ^ gmul(in[4*3+j], 14)) & 0xff);
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = out[4*i+j];
}
}
out = temp;
return out;
}
private byte[] hexStringToByteArray(String string) {
int length = string.length();
int n = (int)Math.ceil((length + 1) / 2);
byte[] result = new byte[n];
for (int i = length - 1; i >= 0 ; i -= 2) {
if (i == 0) {
result[i / 2] = (byte) ((Character.digit('0', 16) << 4)
+ Character.digit(string.charAt(i), 16));
} else {
result[i / 2] = (byte) ((Character.digit(string.charAt(i - 1), 16) << 4)
+ Character.digit(string.charAt(i), 16));
}
}
return result;
}
/* http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java */
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private void printBytes(byte[] input) {
for (int i = 0 ; i < input.length; i++) {
System.out.print(byteToBits(input[i]) + " ");
}
System.out.println();
}
private void printByte(String msg, byte input) {
byte[] temp = new byte[1];
temp[0] = input;
System.out.println(msg + ": " + bytesToHex(temp));
}
private String byteToBits(byte b) {
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 8 ; i++)
buffer.append((int)(b >> (8-(i+1)) & 0x0001));
return buffer.toString();
}
private byte[] getRoundKey(int round) {
byte[] out = new byte[KEY_LENGTH];
out = Arrays.copyOfRange(word, 16*round, 16*round+16);
return out;
}
public static byte[] XORBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length];
for (int i = 0 ; i < in1.length ; i++) {
out[i] = (byte)((in1[i] ^ in2[i]) & 0xff);
}
return out;
}
public byte[] encryptText(byte[] plainText, byte[] key) throws Exception {
byte[] cipher = new byte[BLOCK_LENGTH];
this.word = expandKey(key);
byte[] roundKey = getRoundKey(0);
/* Round 0 */
cipher = XORBytes(plainText, roundKey);
//System.out.println("Round 0\n" + bytesToHex(cipher));
/* Rounds 1 to 9*/
for (int i = 1 ; i < 10 ; i++) {
//System.out.println("Round " + i);
cipher = subBytes(cipher);
//System.out.println("SubBytes: " + bytesToHex(cipher));
cipher = shiftRows(cipher);
//System.out.println("ShiftRows: " + bytesToHex(cipher));
cipher = mixColumns(cipher);
//System.out.println("MixColumns: " + bytesToHex(cipher));
roundKey = getRoundKey(i);
//System.out.println("RoundKey: " + bytesToHex(roundKey));
cipher = XORBytes(cipher, roundKey);
//System.out.println("CIPHER: " + bytesToHex(cipher));
}
/* Round 10*/
//System.out.println("Round 10");
cipher = subBytes(cipher);
//System.out.println("SubBytes: " + bytesToHex(cipher));
cipher = shiftRows(cipher);
//System.out.println("ShiftRows: " + bytesToHex(cipher));
roundKey = getRoundKey(10);
//System.out.println("RoundKey: " + bytesToHex(roundKey));
cipher = XORBytes(cipher, roundKey);
//System.out.println("CIPHER: " + bytesToHex(cipher));
return cipher;
}
public byte[] decryptText(byte[] cipher, byte[] key) throws Exception {
byte[] plainText = new byte[BLOCK_LENGTH];
this.word = expandKey(key);
byte[] roundKey = getRoundKey(10);
/* Round 0 */
plainText = XORBytes(cipher, roundKey);
/* Rounds 1 to 9*/
for (int i = 9 ; i > 0 ; i--) {
plainText = inverseShiftRows(plainText);
plainText = inverseSubBytes(plainText);
roundKey = getRoundKey(i);
plainText = XORBytes(plainText, roundKey);
plainText = inverseMixColumns(plainText);
}
/* Round 10*/
plainText = inverseShiftRows(plainText);
plainText = inverseSubBytes(plainText);
roundKey = getRoundKey(0);
plainText = XORBytes(plainText, roundKey);
return plainText;
}
public static void main(String[] args) throws Exception {
try {
if (args.length != 1) {
System.out.println("Usage: java < classname > < mode >"
+ "\n\t< mode > := (ECB|CBC|OFB|CFB)");
return;
}
/* ECB, CBC, OFB, or CFB */
String mode = args[0];
//String mode = "CFB";
mode = mode.toUpperCase();
AESdecrypt aes = new AESdecrypt(mode);
File keyFile = new File("AESkey.txt");
File textFile = new File("AESplaintext.txt");
File cipherFile = new File("AESciphertext.txt");
FileReader keyFileReader = new FileReader(keyFile);
BufferedReader bufferedReader = new BufferedReader(keyFileReader);
FileInputStream cipherFileInputStream = new FileInputStream(cipherFile);
FileOutputStream textFileOutputStream = new FileOutputStream(textFile);
byte[] key = new byte[(int) keyFile.length()];
String keyString = bufferedReader.readLine();
key = aes.hexStringToByteArray(keyString);
byte[] cipher = new byte[(int) cipherFile.length()];
cipherFileInputStream.read(cipher);
byte[] message = aes.decrypt(cipher, key);
textFileOutputStream.write(message);
textFileOutputStream.flush();
textFileOutputStream.close();
bufferedReader.close();
cipherFileInputStream.close();
System.out.println("Decryption done! Please check AESplaintext.txt for output!");
} catch(Exception exp) {
exp.printStackTrace();
}
}
private byte[] decrypt(byte[] message, byte[] key) throws Exception {
if (message.length < 16) {
System.out.println("Message should be atleast 64 bits");
System.exit(1);
}
if (key.length != 16) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
int length = message.length;
int n = (length + 15)/16 * 16;
byte[] cipher = new byte[n];
if (length == 16) {
if (mode.equals("ECB")) {
return decryptText(message, key);
} else if (mode.equals("CBC")) {
byte[] iv = getInitializationVector();
message = XORBytes(message, iv);
return decryptText(message, key);
} else if (mode.equals("OFB")) {
byte[] nounce = getNounce();
byte[] temp = encryptText(nounce, key);
byte[] result = XORBytes(temp, message);
return result;
} else if (mode.equals("CFB")) {
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
}
int i = 0;
int k = 0;
byte[] feedback = new byte[16];
if (mode.equals("CBC")) {
feedback = getInitializationVector();
} else if (mode.equals("OFB")) {
feedback = getNounce();
} else if (mode.equals("CFB")) {
feedback = getInitializationVectorCFB();
}
while (i < length) {
byte[] block = new byte[16];
byte[] result = new byte[16];
int j = 0;
for (; j < 16 && i < length; j++, i++) {
block[j] = message[i];
}
while (j < 16) {
/* pad with white spaces */
block[j++] = 0x20;
}
//System.out.println("BLOCK: ");
//printBytes(block);
if (mode.equals("ECB")) {
result = decryptText(block, key);
} else if (mode.equals("CBC")) {
result = decryptText(block, key);
result = XORBytes(result, feedback);
feedback = Arrays.copyOfRange(block, 0, 16);
} else if (mode.equals("OFB")) {
result = encryptText(feedback, key);
feedback = Arrays.copyOfRange(result, 0, 16);
result = XORBytes(result, block);
} else if (mode.equals("CFB")) {
result = encryptText(feedback, key);
byte[] resultPart = Arrays.copyOfRange(result, 0, 8);
byte[] blockPart = Arrays.copyOfRange(block, 0, 8);
byte[] temp1 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 8, 16), blockPart);
resultPart = Arrays.copyOfRange(result, 8, 16);
blockPart = Arrays.copyOfRange(block, 8, 16);
result = encryptText(feedback, key);
byte[] temp2 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 8, 16), blockPart);
result = mergeBytes(temp1, temp2);
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
//System.out.println("RESULT: ");
//printBytes(result);
for (j = 0 ; j < 16 && k < cipher.length; j++, k++) {
cipher[k] = result[j];
}
}
return cipher;
}
private byte[] getInitializationVector() {
return hexStringToByteArray("247D8AC4DDB1AA739DC593821D0BC432");
}
private byte[] getInitializationVectorCFB() {
return hexStringToByteArray("247D8AC4DDB1AA739DC593821D0BC432");
}
private byte[] getNounce() {
// char[] hexArray = "0123456789ABCDEF".toCharArray();
// String nounceStr = "";
// for (int i = 0 ; i < 16 ; i++) {
// double random = Math.random();
// int index = (int) (random * 16);
// nounceStr += hexArray[index];
// }
// return hexStringToByteArray(nounceStr);
return hexStringToByteArray("247D8AC4DDB1AA739DC593821D0BC432");
}
private byte[] mergeBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length + in2.length];
int i = 0;
for (int j = 0 ; j < in1.length ; j++) {
out[i++] = in1[j];
}
for (int j = 0 ; j < in2.length ; j++) {
out[i++] = in2[j];
}
return out;
}
}
</pre>
<br />
<b>Output</b>
<br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESkeygen </span><br />
<span style="font-family: Courier New, Courier, monospace;">Key generated and saved in AESkey.txt </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESencrypt </span><br />
<span style="font-family: Courier New, Courier, monospace;">Usage: java < classname > < mode > </span><br />
<span style="font-family: Courier New, Courier, monospace;"> < mode > := (ECB|CBC|OFB|CFB) </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESencrypt ecb </span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check AESciphertext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESdecrypt ecb </span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check AESplaintext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESencrypt cbc </span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check AESciphertext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESdecrypt cbc </span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check AESplaintext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESencrypt ofb </span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check AESciphertext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESdecrypt ofb </span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check AESplaintext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESencrypt cfb </span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check AESciphertext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$ java AESdecrypt cfb </span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check AESplaintext.txt for output! </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace/Copy/crypto/run_aes$
</span><br />
<b><br /></b>
<b>About Input/Output Files</b>
<br />
AESkeygen.java - (output) AESkey.txt<br />
AESencrypt.java - (input) AESkey.txt & AESplaintext.txt (output) AESciphertext.txt<br />
AESdecrypt.java - (input) AESkey.txt & AESciphertext.txt (output) AESplaintext.txtDhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-33979326513621215272014-07-30T21:35:00.002+05:302014-07-30T23:11:02.889+05:30DES Implementation In Java with ECB | CBC | OFB | CFB Modes Of Operation<b><i>Note that these are ONLY basic level programs for easy understanding of the Data Encryption Standard (DES) algorithm</i></b><br />
<br />
<b>Key Generation - DESkeygen.java</b>
<br />
<pre class="java" name="code">
import java.io.File;
import java.io.FileWriter;
public class DESkeygen {
private final File file = new File("DESkey.txt");
private final int KEY_LENGTH = 16;
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public DESkeygen() {
try {
FileWriter fileWriter = new FileWriter(file);
fileWriter.write("");
for (int i = 0 ; i < KEY_LENGTH ; i++) {
double random = Math.random();
int index = (int) (random * 16);
fileWriter.append(hexArray[index]);
fileWriter.flush();
}
fileWriter.close();
System.out.println("Key generated and saved in " + file.getName());
} catch(Exception exp) {
exp.printStackTrace();
}
}
public static void main(String[] args) {
new DESkeygen();
}
}
</pre>
<br />
<b>Encryption - DESencrypt.java</b>
<br />
<pre class="java" name="code">
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Arrays;
public class DESencrypt {
private String mode = null;
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
/* Initial Permutation */
static final int[] IP = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
/* Inverse Initial Permutation */
static final int[] IIP = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/* Expansion Permutation */
static final int[] E = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/* Permutation Function */
static final int[] P = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/* S-Boxes*/
static final int[] S1 = {
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
};
static final int[] S2 = {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
};
static final int[] S3 = {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
};
static final int[] S4 = {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
};
static final int[] S5 = {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
};
static final int[] S6 = {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
};
static final int[] S7 = {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
};
static final int[] S8 = {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
};
/* Permuted Choice One */
static final int[] PC1 = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/* Permuted Choice Two */
static final int[] PC2 = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/* Schedule of Left Shifts */
static final int[] SHIFTS = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
public DESencrypt() {
this.mode = "ECB";
}
public DESencrypt(String mode) {
this.mode = mode;
}
private byte[] performXOR(byte[] one, byte[] two) {
byte[] result = new byte[one.length];
for (int i = 0 ; i < one.length ; i++) {
result[i] = (byte) (one[i] ^ two[i]);
}
return result;
}
private byte[] permute(byte[] input, int[] mapping) {
int byteCount = 1 + (mapping.length - 1) / 8;
byte[] output = new byte[byteCount];
int pos;
for (int i = 0 ; i < mapping.length ; i++) {
pos = mapping[i] - 1;
int value = getBitFromArray(input, pos);
setBitInArray(output, i, value);
}
return output;
}
private int getBitFromArray(byte[] array, int pos) {
int value;
int bytePos = pos / 8;
int bitPos = pos % 8;
value = (array[bytePos] >> (8 - (bitPos + 1))) & 0x0001;
/* eg: right shift selected byte 5 times to get 3rd bit
* (bitPos = 2) at rightmost position and
* then AND with 0x0001*/
return value;
}
private void setBitInArray(byte[] input, int pos, int value) {
int bytePos = pos / 8;
int bitPos = pos % 8;
byte old = input[bytePos];
old = (byte) (((0xFF7F >> bitPos) & old) & 0x00FF);
byte newByte = (byte) ((value << (8 - (bitPos + 1))) | old);
input[bytePos] = newByte;
}
private byte[] hexStringToByteArray(String string) {
int length = string.length();
int n = (int)Math.ceil((length + 1) / 2);
byte[] result = new byte[n];
for (int i = length - 1; i >= 0 ; i -= 2) {
if (i == 0) {
result[i / 2] = (byte) ((Character.digit('0', 16) << 4)
+ Character.digit(string.charAt(i), 16));
} else {
result[i / 2] = (byte) ((Character.digit(string.charAt(i - 1), 16) << 4)
+ Character.digit(string.charAt(i), 16));
}
}
return result;
}
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private void printBytes(byte[] input) {
for (int i = 0 ; i < input.length; i++) {
System.out.print(byteToBits(input[i]) + " ");
}
System.out.println();
}
private String byteToBits(byte b) {
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 8 ; i++)
buffer.append((int)(b >> (8-(i+1)) & 0x0001));
return buffer.toString();
}
private byte[] getBits(byte[] input, int startPos, int length) {
int noOfBytes = (length-1)/8 + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < length ; i++) {
int value = getBitFromArray(input, startPos + i);
setBitInArray(output, i, value);
}
return output;
}
private byte[] rotateLeft(byte[] input, int step, int length) {
int noOfBytes = (length - 1) / 8 + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < length ; i++) {
int value = getBitFromArray(input, (i + step) % length);
setBitInArray(output, i, value);
}
return output;
}
private byte[] concatBits(byte[] one, int oneLength,
byte[] two, int twoLength) {
int noOfBytes = (oneLength + twoLength - 1) / 8 + 1;
byte[] output = new byte[noOfBytes];
int i = 0, j = 0;
for (; i < oneLength ; i++) {
int value = getBitFromArray(one, i);
setBitInArray(output, j, value);
j++;
}
for (i = 0 ; i < twoLength ; i++) {
int value = getBitFromArray(two, i);
setBitInArray(output, j, value);
j++;
}
return output;
}
private byte[][] getSubKeys(byte[] masterKey) {
int noOfSubKeys = SHIFTS.length;
int keySize = PC1.length;
byte[] key = permute(masterKey, PC1);
byte[][] subKeys = new byte[noOfSubKeys][keySize];
byte[] leftHalf = getBits(key, 0, keySize/2);
byte[] rightHalf = getBits(key, keySize/2, keySize/2);
for (int i = 0 ; i < noOfSubKeys ; i++) {
leftHalf = rotateLeft(leftHalf, SHIFTS[i], keySize/2);
rightHalf = rotateLeft(rightHalf, SHIFTS[i], keySize/2);
byte[] subKey = concatBits(leftHalf, keySize/2, rightHalf, keySize/2);
subKeys[i] = permute(subKey, PC2);
}
return subKeys;
}
public byte[] crypt(byte[] message, byte[] key, String operation) {
if (message.length < 8) {
System.out.println("Message should be atleast 64 bits");
System.exit(1);
}
if (key.length != 8) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
int length = message.length;
int n = (length + 7)/8 * 8;
byte[] cipher = new byte[n];
if (length == 8) {
if (mode.equals("ECB")) {
return cryptText(message, key, operation);
} else if (mode.equals("CBC")) {
byte[] iv = getInitializationVector();
message = XORBytes(message, iv);
return cryptText(message, key, operation);
} else if (mode.equals("OFB")) {
byte[] nounce = getNounce();
byte[] temp = cryptText(nounce, key, operation);
byte[] result = XORBytes(temp, message);
return result;
} else if (mode.equals("CFB")) {
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
}
int i = 0;
int k = 0;
byte[] feedback = new byte[8];
if (mode.equals("CBC")) {
feedback = getInitializationVector();
} else if (mode.equals("OFB")) {
feedback = getNounce();
} else if (mode.equals("CFB")) {
feedback = getInitializationVectorCFB();
}
while (i < length) {
byte[] block = new byte[8];
byte[] result = new byte[8];
int j = 0;
for (; j < 8 && i < length; j++, i++) {
block[j] = message[i];
}
while (j < 8) {
/* pad with white spaces */
block[j++] = 0x20;
}
//System.out.println("BLOCK: ");
//printBytes(block);
if (mode.equals("ECB")) {
result = cryptText(block, key, operation);
} else if (mode.equals("CBC")) {
if (operation.equals("encrypt")) {
block = XORBytes(block, feedback);
result = cryptText(block, key, operation);
feedback = Arrays.copyOfRange(result, 0, 8);
} else if (operation.equals("decrypt")) {
result = cryptText(block, key, operation);
result = XORBytes(result, feedback);
feedback = Arrays.copyOfRange(block, 0, 8);
}
} else if (mode.equals("OFB")) {
result = cryptText(feedback, key, operation);
feedback = Arrays.copyOfRange(result, 0, 8);
result = XORBytes(result, block);
} else if (mode.equals("CFB")) {
if (operation.equals("encrypt")) {
result = cryptText(feedback, key, operation);
byte[] resultPart = Arrays.copyOfRange(result, 0, 4);
byte[] blockPart = Arrays.copyOfRange(block, 0, 4);
byte[] temp1 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), temp1);
resultPart = Arrays.copyOfRange(result, 4, 8);
blockPart = Arrays.copyOfRange(block, 4, 8);
result = cryptText(feedback, key, operation);
byte[] temp2 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), temp2);
result = mergeBytes(temp1, temp2);
} else if (operation.equals("decrypt")) {
result = cryptText(feedback, key, "encrypt");
byte[] resultPart = Arrays.copyOfRange(result, 0, 4);
byte[] blockPart = Arrays.copyOfRange(block, 0, 4);
byte[] temp1 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), blockPart);
resultPart = Arrays.copyOfRange(result, 4, 8);
blockPart = Arrays.copyOfRange(block, 4, 8);
result = cryptText(feedback, key, "encrypt");
byte[] temp2 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), blockPart);
result = mergeBytes(temp1, temp2);
}
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
//System.out.println("RESULT: ");
//printBytes(result);
for (j = 0 ; j < 8 && k < cipher.length; j++, k++) {
cipher[k] = result[j];
}
}
return cipher;
}
private byte[] getInitializationVector() {
return hexStringToByteArray("DCBE6AE7EA5D5C61");
}
private byte[] getInitializationVectorCFB() {
return hexStringToByteArray("A5D5C61EFADB4351");
}
private byte[] getNounce() {
// char[] hexArray = "0123456789ABCDEF".toCharArray();
// String nounceStr = "";
// for (int i = 0 ; i < 16 ; i++) {
// double random = Math.random();
// int index = (int) (random * 16);
// nounceStr += hexArray[index];
// }
// return hexStringToByteArray(nounceStr);
return hexStringToByteArray("DCBE6AE7EA5D5C61");
}
private byte[] mergeBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length + in2.length];
int i = 0;
for (int j = 0 ; j < in1.length ; j++) {
out[i++] = in1[j];
}
for (int j = 0 ; j < in2.length ; j++) {
out[i++] = in2[j];
}
return out;
}
public byte[] cryptText(byte[] message, byte[] key, String operation) {
if (message.length != 8) {
System.out.println("Message should be 64 bits");
System.exit(1);
}
if (key.length != 8) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
byte[] result = null;
int blockSize = IP.length;
byte[][] subKeys = getSubKeys(key);
int noOfRounds = subKeys.length;
/**
* Initial Permutation
*/
message = permute(message, IP);
/**
* Split message into two halves
*/
byte[] leftHalf = getBits(message, 0, blockSize/2);
byte[] rightHalf = getBits(message, blockSize/2, blockSize/2);
for (int i = 0 ; i < noOfRounds ; i++) {
byte[] temp = rightHalf;
/**
* Expansion
*/
rightHalf = permute(rightHalf, E);
/**
* XOR rightHalf with roundKey
*/
byte[] roundKey = null;
if (operation.equalsIgnoreCase("encrypt")) {
roundKey = subKeys[i];
} else if (operation.equalsIgnoreCase("decrypt")) {
roundKey = subKeys[noOfRounds - i - 1];
} else {
System.out.println("Unsupported operation");
System.exit(0);
}
rightHalf = performXOR(rightHalf, roundKey);
/**
* S-Box
*/
rightHalf = sBox(rightHalf);
/**
* Permutation
*/
rightHalf = permute(rightHalf, P);
/**
* XOR rightHalf with leftHalf
*/
rightHalf = performXOR(rightHalf, leftHalf);
/**
* L(i) = R(i-1)
*/
leftHalf = temp;
}
/**
* 32 bit swap
*/
byte[] concatHalves = concatBits(rightHalf, blockSize/2, leftHalf, blockSize/2);
/**
* Inverse Initial Permutation
*/
result = permute(concatHalves, IIP);
return result;
}
public static byte[] XORBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length];
for (int i = 0 ; i < in1.length ; i++) {
out[i] = (byte)((in1[i] ^ in2[i]) & 0xff);
}
return out;
}
private byte[] sBox(byte[] input) {
/**
* Split input to 6-bit blocks
*/
input = split(input,6);
byte[] output = new byte[input.length/2];
int leftHalf = 0;
for (int i = 0; i < input.length ; i++) {
byte block = input[i];
/**
* row - first and last bits
* column - 4 bits in the middle
*/
int row = 2 * (block >> 7 & 0x0001) + (block >> 2 & 0x0001);
int col = block >> 3 & 0x000F;
int[] selectedSBox = getSBox(i);
int rightHalf = selectedSBox[16 * row + col];
if (i % 2 == 0) {
leftHalf = rightHalf;
} else {
output[i/2] = (byte) (16 * leftHalf + rightHalf);
leftHalf = 0;
}
}
return output;
}
private int[] getSBox(int i) {
switch (i) {
case 0: return S1;
case 1: return S2;
case 2: return S3;
case 3: return S4;
case 4: return S5;
case 5: return S6;
case 6: return S7;
case 7: return S8;
default: return null;
}
}
private byte[] split(byte[] input, int length) {
int noOfBytes = (8 * input.length - 1) / length + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < noOfBytes ; i++) {
for (int j = 0; j < length ; j++) {
int value = getBitFromArray(input, length * i + j);
setBitInArray(output, 8 * i + j, value);
}
}
return output;
}
public static void main(String[] args) {
try {
if (args.length != 1) {
System.out.println("Usage: java < classname > < mode >"
+ "\n\t< mode > := (ECB|CBC|OFB|CFB)");
return;
}
/* ECB, CBC, OFB, or CFB */
String mode = args[0];
mode = mode.toUpperCase();
DESencrypt des = new DESencrypt(mode);
File keyFile = new File("DESkey.txt");
File textFile = new File("DESplaintext.txt");
File cipherFile = new File("DESciphertext.txt");
FileReader keyFileReader = new FileReader(keyFile);
BufferedReader bufferedReader = new BufferedReader(keyFileReader);
FileInputStream textFileInputStream = new FileInputStream(textFile);
FileOutputStream cipherFileOutputStream = new FileOutputStream(cipherFile);
byte[] key = new byte[(int) keyFile.length()];
String keyString = bufferedReader.readLine();
key = des.hexStringToByteArray(keyString);
byte[] message = new byte[(int) textFile.length()];
textFileInputStream.read(message);
byte[] cipher = des.crypt(message, key, "encrypt");
cipherFileOutputStream.write(cipher);
cipherFileOutputStream.flush();
cipherFileOutputStream.close();
bufferedReader.close();
textFileInputStream.close();
System.out.println("Encryption done! Please check DESciphertext.txt for output!");
} catch(Exception exp) {
exp.printStackTrace();
}
}
}
</pre>
<br />
<b>Decryption - DESdecrypt.java</b>
<br />
<pre class="java" name="code">
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Arrays;
public class DESdecrypt {
private String mode = null;
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
/* Initial Permutation */
static final int[] IP = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
/* Inverse Initial Permutation */
static final int[] IIP = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/* Expansion Permutation */
static final int[] E = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/* Permutation Function */
static final int[] P = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/* S-Boxes*/
static final int[] S1 = {
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
};
static final int[] S2 = {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
};
static final int[] S3 = {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
};
static final int[] S4 = {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
};
static final int[] S5 = {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
};
static final int[] S6 = {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
};
static final int[] S7 = {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
};
static final int[] S8 = {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
};
/* Permuted Choice One */
static final int[] PC1 = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/* Permuted Choice Two */
static final int[] PC2 = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/* Schedule of Left Shifts */
static final int[] SHIFTS = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
public DESdecrypt() {
this.mode = "ECB";
}
public DESdecrypt(String mode) {
this.mode = mode;
}
private byte[] performXOR(byte[] one, byte[] two) {
byte[] result = new byte[one.length];
for (int i = 0 ; i < one.length ; i++) {
result[i] = (byte) (one[i] ^ two[i]);
}
return result;
}
private byte[] permute(byte[] input, int[] mapping) {
int byteCount = 1 + (mapping.length - 1) / 8;
byte[] output = new byte[byteCount];
int pos;
for (int i = 0 ; i < mapping.length ; i++) {
pos = mapping[i] - 1;
int value = getBitFromArray(input, pos);
setBitInArray(output, i, value);
}
return output;
}
private int getBitFromArray(byte[] array, int pos) {
int value;
int bytePos = pos / 8;
int bitPos = pos % 8;
value = (array[bytePos] >> (8 - (bitPos + 1))) & 0x0001;
/* eg: right shift selected byte 5 times to get 3rd bit
* (bitPos = 2) at rightmost position and
* then AND with 0x0001*/
return value;
}
private void setBitInArray(byte[] input, int pos, int value) {
int bytePos = pos / 8;
int bitPos = pos % 8;
byte old = input[bytePos];
old = (byte) (((0xFF7F >> bitPos) & old) & 0x00FF);
byte newByte = (byte) ((value << (8 - (bitPos + 1))) | old);
input[bytePos] = newByte;
}
private byte[] hexStringToByteArray(String string) {
int length = string.length();
int n = (int)Math.ceil((length + 1) / 2);
byte[] result = new byte[n];
for (int i = length - 1; i >= 0 ; i -= 2) {
if (i == 0) {
result[i / 2] = (byte) ((Character.digit('0', 16) << 4)
+ Character.digit(string.charAt(i), 16));
} else {
result[i / 2] = (byte) ((Character.digit(string.charAt(i - 1), 16) << 4)
+ Character.digit(string.charAt(i), 16));
}
}
return result;
}
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private void printBytes(byte[] input) {
for (int i = 0 ; i < input.length; i++) {
System.out.print(byteToBits(input[i]) + " ");
}
System.out.println();
}
private String byteToBits(byte b) {
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 8 ; i++)
buffer.append((int)(b >> (8-(i+1)) & 0x0001));
return buffer.toString();
}
private byte[] getBits(byte[] input, int startPos, int length) {
int noOfBytes = (length-1)/8 + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < length ; i++) {
int value = getBitFromArray(input, startPos + i);
setBitInArray(output, i, value);
}
return output;
}
private byte[] rotateLeft(byte[] input, int step, int length) {
int noOfBytes = (length - 1) / 8 + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < length ; i++) {
int value = getBitFromArray(input, (i + step) % length);
setBitInArray(output, i, value);
}
return output;
}
private byte[] concatBits(byte[] one, int oneLength,
byte[] two, int twoLength) {
int noOfBytes = (oneLength + twoLength - 1) / 8 + 1;
byte[] output = new byte[noOfBytes];
int i = 0, j = 0;
for (; i < oneLength ; i++) {
int value = getBitFromArray(one, i);
setBitInArray(output, j, value);
j++;
}
for (i = 0 ; i < twoLength ; i++) {
int value = getBitFromArray(two, i);
setBitInArray(output, j, value);
j++;
}
return output;
}
private byte[][] getSubKeys(byte[] masterKey) {
int noOfSubKeys = SHIFTS.length;
int keySize = PC1.length;
byte[] key = permute(masterKey, PC1);
byte[][] subKeys = new byte[noOfSubKeys][keySize];
byte[] leftHalf = getBits(key, 0, keySize/2);
byte[] rightHalf = getBits(key, keySize/2, keySize/2);
for (int i = 0 ; i < noOfSubKeys ; i++) {
leftHalf = rotateLeft(leftHalf, SHIFTS[i], keySize/2);
rightHalf = rotateLeft(rightHalf, SHIFTS[i], keySize/2);
byte[] subKey = concatBits(leftHalf, keySize/2, rightHalf, keySize/2);
subKeys[i] = permute(subKey, PC2);
}
return subKeys;
}
public byte[] crypt(byte[] message, byte[] key, String operation) {
if (message.length < 8) {
System.out.println("Message should be atleast 64 bits");
System.exit(1);
}
if (key.length != 8) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
int length = message.length;
int n = (length + 7)/8 * 8;
byte[] cipher = new byte[n];
if (length == 8) {
if (mode.equals("ECB")) {
return cryptText(message, key, operation);
} else if (mode.equals("CBC")) {
byte[] iv = getInitializationVector();
message = XORBytes(message, iv);
return cryptText(message, key, operation);
} else if (mode.equals("OFB")) {
byte[] nounce = getNounce();
byte[] temp = cryptText(nounce, key, "encrypt");
byte[] result = XORBytes(temp, message);
return result;
} else if (mode.equals("CFB")) {
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
}
int i = 0;
int k = 0;
byte[] feedback = new byte[8];
if (mode.equals("CBC")) {
feedback = getInitializationVector();
} else if (mode.equals("OFB")) {
feedback = getNounce();
} else if (mode.equals("CFB")) {
feedback = getInitializationVectorCFB();
}
while (i < length) {
byte[] block = new byte[8];
byte[] result = new byte[8];
int j = 0;
for (; j < 8 && i < length; j++, i++) {
block[j] = message[i];
}
while (j < 8) {
/* pad with white spaces */
block[j++] = 0x20;
}
//System.out.println("BLOCK: ");
//printBytes(block);
if (mode.equals("ECB")) {
result = cryptText(block, key, operation);
} else if (mode.equals("CBC")) {
if (operation.equals("encrypt")) {
block = XORBytes(block, feedback);
result = cryptText(block, key, operation);
feedback = Arrays.copyOfRange(result, 0, 8);
} else if (operation.equals("decrypt")) {
result = cryptText(block, key, operation);
result = XORBytes(result, feedback);
feedback = Arrays.copyOfRange(block, 0, 8);
}
} else if (mode.equals("OFB")) {
result = cryptText(feedback, key, "encrypt");
feedback = Arrays.copyOfRange(result, 0, 8);
result = XORBytes(result, block);
} else if (mode.equals("CFB")) {
if (operation.equals("encrypt")) {
result = cryptText(feedback, key, operation);
byte[] resultPart = Arrays.copyOfRange(result, 0, 4);
byte[] blockPart = Arrays.copyOfRange(block, 0, 4);
byte[] temp1 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), temp1);
resultPart = Arrays.copyOfRange(result, 4, 8);
blockPart = Arrays.copyOfRange(block, 4, 8);
result = cryptText(feedback, key, operation);
byte[] temp2 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), temp2);
result = mergeBytes(temp1, temp2);
} else if (operation.equals("decrypt")) {
result = cryptText(feedback, key, "encrypt");
byte[] resultPart = Arrays.copyOfRange(result, 0, 4);
byte[] blockPart = Arrays.copyOfRange(block, 0, 4);
byte[] temp1 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), blockPart);
resultPart = Arrays.copyOfRange(result, 4, 8);
blockPart = Arrays.copyOfRange(block, 4, 8);
result = cryptText(feedback, key, "encrypt");
byte[] temp2 = XORBytes(resultPart, blockPart);
feedback = mergeBytes(Arrays.copyOfRange(result, 4, 8), blockPart);
result = mergeBytes(temp1, temp2);
}
} else {
System.out.println("Unsupported mode of operation!");
return null;
}
//System.out.println("RESULT: ");
//printBytes(result);
for (j = 0 ; j < 8 && k < cipher.length; j++, k++) {
cipher[k] = result[j];
}
}
return cipher;
}
private byte[] getInitializationVector() {
return hexStringToByteArray("DCBE6AE7EA5D5C61");
}
private byte[] getInitializationVectorCFB() {
return hexStringToByteArray("A5D5C61EFADB4351");
}
private byte[] getNounce() {
// char[] hexArray = "0123456789ABCDEF".toCharArray();
// String nounceStr = "";
// for (int i = 0 ; i < 16 ; i++) {
// double random = Math.random();
// int index = (int) (random * 16);
// nounceStr += hexArray[index];
// }
// return hexStringToByteArray(nounceStr);
return hexStringToByteArray("DCBE6AE7EA5D5C61");
}
private byte[] mergeBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length + in2.length];
int i = 0;
for (int j = 0 ; j < in1.length ; j++) {
out[i++] = in1[j];
}
for (int j = 0 ; j < in2.length ; j++) {
out[i++] = in2[j];
}
return out;
}
public byte[] cryptText(byte[] message, byte[] key, String operation) {
if (message.length != 8) {
System.out.println("Message should be 64 bits");
System.exit(1);
}
if (key.length != 8) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
byte[] result = null;
int blockSize = IP.length;
byte[][] subKeys = getSubKeys(key);
int noOfRounds = subKeys.length;
/**
* Initial Permutation
*/
message = permute(message, IP);
/**
* Split message into two halves
*/
byte[] leftHalf = getBits(message, 0, blockSize/2);
byte[] rightHalf = getBits(message, blockSize/2, blockSize/2);
for (int i = 0 ; i < noOfRounds ; i++) {
byte[] temp = rightHalf;
/**
* Expansion
*/
rightHalf = permute(rightHalf, E);
/**
* XOR rightHalf with roundKey
*/
byte[] roundKey = null;
if (operation.equalsIgnoreCase("encrypt")) {
roundKey = subKeys[i];
} else if (operation.equalsIgnoreCase("decrypt")) {
roundKey = subKeys[noOfRounds - i - 1];
} else {
System.out.println("Unsupported operation");
System.exit(0);
}
rightHalf = performXOR(rightHalf, roundKey);
/**
* S-Box
*/
rightHalf = sBox(rightHalf);
/**
* Permutation
*/
rightHalf = permute(rightHalf, P);
/**
* XOR rightHalf with leftHalf
*/
rightHalf = performXOR(rightHalf, leftHalf);
/**
* L(i) = R(i-1)
*/
leftHalf = temp;
}
/**
* 32 bit swap
*/
byte[] concatHalves = concatBits(rightHalf, blockSize/2, leftHalf, blockSize/2);
/**
* Inverse Initial Permutation
*/
result = permute(concatHalves, IIP);
return result;
}
public static byte[] XORBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[in1.length];
for (int i = 0 ; i < in1.length ; i++) {
out[i] = (byte)((in1[i] ^ in2[i]) & 0xff);
}
return out;
}
private byte[] sBox(byte[] input) {
/**
* Split input to 6-bit blocks
*/
input = split(input,6);
byte[] output = new byte[input.length/2];
int leftHalf = 0;
for (int i = 0; i < input.length ; i++) {
byte block = input[i];
/**
* row - first and last bits
* column - 4 bits in the middle
*/
int row = 2 * (block >> 7 & 0x0001) + (block >> 2 & 0x0001);
int col = block >> 3 & 0x000F;
int[] selectedSBox = getSBox(i);
int rightHalf = selectedSBox[16 * row + col];
if (i % 2 == 0) {
leftHalf = rightHalf;
} else {
output[i/2] = (byte) (16 * leftHalf + rightHalf);
leftHalf = 0;
}
}
return output;
}
private int[] getSBox(int i) {
switch (i) {
case 0: return S1;
case 1: return S2;
case 2: return S3;
case 3: return S4;
case 4: return S5;
case 5: return S6;
case 6: return S7;
case 7: return S8;
default: return null;
}
}
private byte[] split(byte[] input, int length) {
int noOfBytes = (8 * input.length - 1) / length + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < noOfBytes ; i++) {
for (int j = 0; j < length ; j++) {
int value = getBitFromArray(input, length * i + j);
setBitInArray(output, 8 * i + j, value);
}
}
return output;
}
public static void main(String[] args) {
try {
if (args.length != 1) {
System.out.println("Usage: java < classname > < mode >"
+ "\n\t< mode > := (ECB|CBC|OFB|CFB)");
return;
}
/* ECB, CBC, OFB, or CFB */
String mode = args[0];
mode = mode.toUpperCase();
DESdecrypt des = new DESdecrypt(mode);
File keyFile = new File("DESkey.txt");
File textFile = new File("DESplaintext.txt");
File cipherFile = new File("DESciphertext.txt");
FileReader keyFileReader = new FileReader(keyFile);
BufferedReader bufferedReader = new BufferedReader(keyFileReader);
FileInputStream cipherFileInputStream = new FileInputStream(cipherFile);
FileOutputStream textFileOutputStream = new FileOutputStream(textFile);
byte[] key = new byte[(int) keyFile.length()];
String keyString = bufferedReader.readLine();
key = des.hexStringToByteArray(keyString);
byte[] cipher = new byte[(int) cipherFile.length()];
cipherFileInputStream.read(cipher);
byte[] message = des.crypt(cipher, key, "decrypt");
textFileOutputStream.write(message);
textFileOutputStream.flush();
textFileOutputStream.close();
bufferedReader.close();
cipherFileInputStream.close();
System.out.println("Decryption done! Please check DESplaintext.txt for output!");
} catch(Exception exp) {
exp.printStackTrace();
}
}
}
</pre>
<br />
<b>Output</b>
<br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESkeygen</span><br />
<span style="font-family: Courier New, Courier, monospace;">Key generated and saved in DESkey.txt</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESencrypt</span><br />
<span style="font-family: Courier New, Courier, monospace;">Usage: java <classname> <mode></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><mode> := (ECB|CBC|OFB|CFB)</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESencrypt ecb</span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check DESciphertext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESdecrypt ecb</span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check DESplaintext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESencrypt cbc</span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check DESciphertext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESdecrypt cbc</span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check DESplaintext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESencrypt ofb</span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check DESciphertext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESdecrypt ofb</span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check DESplaintext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESencrypt cfb</span><br />
<span style="font-family: Courier New, Courier, monospace;">Encryption done! Please check DESciphertext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESdecrypt cfb</span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check DESplaintext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ java DESdecrypt cfb</span><br />
<span style="font-family: Courier New, Courier, monospace;">Decryption done! Please check DESplaintext.txt for output!</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~/workspace$ </span><br />
<br />
<classname><mode><mode>
<b>About Input/Output Files</b>
<br />
DESkeygen.java - (output) DESkey.txt </mode></mode></classname><br />
<classname><mode><mode>DESencrypt.java - (input) DESkey.txt & DESplaintext.txt (output) DESciphertext.txt </mode></mode></classname><br />
<classname><mode><mode>DESdecrypt.java - (input) DESkey.txt & DESciphertext.txt (output) DESplaintext.txt</mode></mode></classname>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-48290503416135703732014-07-30T12:48:00.005+05:302014-07-30T12:48:53.334+05:30AES Implementation in Java<b><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">AES.java</span></b>
<br />
<br />
<pre class="java" name="code">
import java.util.Arrays;
public class AES {
private static final int BITS = 16;
private static final int ROUNDS = 10;
private static final int NO_OF_WORDS_IN_KEY = 44;
private static final int KEY_LENGTH = 16;
private static final int BLOCK_LENGTH = 16;
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
int[] RC = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36};
Word[] Rcon = new Word[ROUNDS];
private byte[] word = null;
static final int[] sBox = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static final int[] invSBox = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
public AES() {
for (int i = 0 ; i < ROUNDS ; i++) {
Rcon[i] = new Word();
byte[] temp = new byte[4];
temp[0] = (byte) (RC[i] & 0xff);
temp[1] = 0;
temp[2] = 0;
temp[3] = 0;
Rcon[i].setWord(temp);
}
word = new byte[NO_OF_WORDS_IN_KEY];
}
/* Ref: http://www.samiam.org/galois.html */
/* Galois Addition*/
byte gadd(byte a, byte b) {
return (byte) ((a ^ b) & 0xff);
}
/* Galois Subtraction*/
byte gsub(byte a, byte b) {
return (byte) ((a ^ b) & 0xff);
}
/* Galois Multiplication*/
byte gmul(byte a, byte b) {
byte p = 0;
int counter;
byte high_bit_set;
byte byte0x80 = hexStringToByteArray("80")[0];
for (counter = 0 ; counter < 8 ; counter++) {
if((b & 0x01) == 1) {
//System.out.println("lower bit of b is set");
p = (byte)((p ^ a) & 0xff);
}
high_bit_set = (byte) (a & 0x80);
//printByte("high_bit_set", high_bit_set);
a <<= 1;
if (high_bit_set == byte0x80) {
//System.out.println("higher bit of a is set");
a = (byte)((a ^ 0x1b) & 0xff);
}
b = (byte)((b >> 1) & 0x7f);
//printByte("a", a);
//printByte("b", b);
//printByte("p", p);
}
return p;
}
byte gmul(byte a, int b) {
byte t = (byte)(b & 0xff);
return gmul(a, t);
}
/* Key Expansion */
private byte[] expandKey(byte[] key) throws Exception {
//System.out.println(key.length);
//System.out.println(bytesToHex(key));
if(key.length != KEY_LENGTH) {
throw new Exception("Key should be of length, 128 bits");
}
Word[] w = new Word[NO_OF_WORDS_IN_KEY];
Word temp;
for (int i = 0; i < 4; i++) {
w[i] = new Word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]);
//System.out.println("w" + i + " = " + w[i]);
}
for (int i = 4; i < 44; i++) {
temp = w[i-1];
Word temp1 = new Word();
temp1.setWord(temp.getWord());
//System.out.println("w" + (i-1) + " = " + temp);
if (i % 4 == 0) {
temp1.rotWord();
//System.out.println("Rot=" + temp1);
temp1.subWord();
//System.out.println("Sub=" + temp1);
temp1 = Word.XORWords(temp1, Rcon[(i/4) - 1]);
//System.out.println("Rcon" + temp1);
}
w[i] = Word.XORWords(w[i-4], temp1);
//System.out.println("w" + i + " = " + w[i]);
}
return Word.wordsToBytes(w);
}
/* Substitute Bytes */
private byte[] subBytes(byte[] in) {
byte[] out = new byte[BITS];
for (int i = 0 ; i < BITS ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) sBox[row * BITS + col];
}
return out;
}
/* Inverse Substitute Bytes */
private byte[] inverseSubBytes(byte[] in) {
byte[] out = new byte[BITS];
for (int i = 0 ; i < BITS ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) invSBox[row * BITS + col];
}
return out;
}
/* Shift Rows */
private byte[] shiftRows(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
//System.out.println("temp: " + bytesToHex(temp));
for (int i = 0 ; i < BITS/4 ; i++) {
byte[] a = Arrays.copyOfRange(temp, (4 * i), (4 * i + 4));
byte[] b = leftShift(a, i);
in[4*i] = b[0];
in[4*i+1] = b[1];
in[4*i+2] = b[2];
in[4*i+3] = b[3];
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*j+i] = in[4*i+j];
}
}
return out;
}
private byte[] leftShift(byte[] in, int times) {
byte[] out = new byte[4];
out = Arrays.copyOfRange(in, 0, 4);
for (int i = 0 ; i < times ; i++) {
out[0] = in[1];
out[1] = in[2];
out[2] = in[3];
out[3] = in[0];
in = Arrays.copyOfRange(out, 0, 4);
}
return out;
}
/* Inverse Shift Rows */
private byte[] inverseShiftRows(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
for (int i = 0 ; i < BITS/4 ; i++) {
byte[] a = Arrays.copyOfRange(temp, (4 * i), (4 * i + 4));
byte[] b = rightShift(a, i);
in[4 * i] = b[0];
in[4 * i + 1] = b[1];
in[4 * i + 2] = b[2];
in[4 * i + 3] = b[3];
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*j+i] = in[4*i+j];
}
}
return out;
}
private byte[] rightShift(byte[] in, int times) {
byte[] out = new byte[4];
out = Arrays.copyOfRange(in, 0, 4);
for (int i = 0 ; i < times ; i++) {
out[0] = in[3];
out[1] = in[0];
out[2] = in[1];
out[3] = in[2];
in = Arrays.copyOfRange(out, 0, 4);
}
return out;
}
/* Mix Columns */
private byte[] mixColumns(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
in = temp;
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*0+j] = (byte) ((gmul(in[4*0+j], 2) ^ gmul(in[4*1+j], 3) ^ in[4*2+j] ^ in[4*3+j]) & 0xff);
out[4*1+j] = (byte) ((in[4*0+j] ^ gmul(in[4*1+j], 2) ^ gmul(in[4*2+j], 3) ^ in[4*3+j]) & 0xff);
out[4*2+j] = (byte) ((in[4*0+j] ^ in[4*1+j] ^ gmul(in[4*2+j], 2) ^ gmul(in[4*3+j], 3)) & 0xff);
out[4*3+j] = (byte) ((gmul(in[4*0+j], 3) ^ in[4*1+j] ^ in[4*2+j] ^ gmul(in[4*3+j], 2)) & 0xff);
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = out[4*i+j];
}
}
out = temp;
return out;
}
/* Inverse Mix Columns */
private byte[] inverseMixColumns(byte[] in) {
byte[] out = new byte[BITS];
byte[] temp = new byte[BITS];
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = in[4*i+j];
}
}
in = temp;
for (int j = 0 ; j < BITS/4 ; j++) {
out[4*0+j] = (byte) ((gmul(in[4*0+j], 14) ^ gmul(in[4*1+j], 11) ^ gmul(in[4*2+j], 13) ^ gmul(in[4*3+j], 9)) & 0xff);
out[4*1+j] = (byte) ((gmul(in[4*0+j], 9) ^ gmul(in[4*1+j], 14) ^ gmul(in[4*2+j], 11) ^ gmul(in[4*3+j], 13)) & 0xff);
out[4*2+j] = (byte) ((gmul(in[4*0+j], 13) ^ gmul(in[4*1+j], 9) ^ gmul(in[4*2+j], 14) ^ gmul(in[4*3+j], 11)) & 0xff);
out[4*3+j] = (byte) ((gmul(in[4*0+j], 11) ^ gmul(in[4*1+j], 13) ^ gmul(in[4*2+j], 9) ^ gmul(in[4*3+j], 14)) & 0xff);
}
for (int i = 0 ; i < BITS/4 ; i++) {
for (int j = 0 ; j < BITS/4 ; j++) {
temp[4*j+i] = out[4*i+j];
}
}
out = temp;
return out;
}
private byte[] hexStringToByteArray(String string) {
int length = string.length();
int n = (int)Math.ceil((length + 1) / 2);
byte[] result = new byte[n];
for (int i = length - 1; i >= 0 ; i -= 2) {
if (i == 0) {
result[i / 2] = (byte) ((Character.digit('0', 16) << 4)
+ Character.digit(string.charAt(i), 16));
} else {
result[i / 2] = (byte) ((Character.digit(string.charAt(i - 1), 16) << 4)
+ Character.digit(string.charAt(i), 16));
}
}
return result;
}
/* http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java */
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
private void printBytes(byte[] input) {
for (int i = 0 ; i < input.length; i++) {
System.out.print(byteToBits(input[i]) + " ");
}
System.out.println();
}
private void printByte(String msg, byte input) {
byte[] temp = new byte[1];
temp[0] = input;
System.out.println(msg + ": " + bytesToHex(temp));
}
private String byteToBits(byte b) {
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 8 ; i++)
buffer.append((int)(b >> (8-(i+1)) & 0x0001));
return buffer.toString();
}
private byte[] getRoundKey(int round) {
byte[] out = new byte[KEY_LENGTH];
out = Arrays.copyOfRange(word, 16*round, 16*round+16);
return out;
}
public static byte[] XORBytes(byte[] in1, byte[] in2) {
byte[] out = new byte[BLOCK_LENGTH];
for (int i = 0 ; i < BLOCK_LENGTH ; i++) {
out[i] = (byte)((in1[i] ^ in2[i]) & 0xff);
}
return out;
}
public byte[] encrypt(byte[] plainText, byte[] key) throws Exception {
byte[] cipher = new byte[BLOCK_LENGTH];
this.word = expandKey(key);
byte[] roundKey = getRoundKey(0);
/* Round 0 */
cipher = XORBytes(plainText, roundKey);
//System.out.println("Round 0\n" + bytesToHex(cipher));
/* Rounds 1 to 9*/
for (int i = 1 ; i < 10 ; i++) {
//System.out.println("Round " + i);
cipher = subBytes(cipher);
//System.out.println("SubBytes: " + bytesToHex(cipher));
cipher = shiftRows(cipher);
//System.out.println("ShiftRows: " + bytesToHex(cipher));
cipher = mixColumns(cipher);
//System.out.println("MixColumns: " + bytesToHex(cipher));
roundKey = getRoundKey(i);
//System.out.println("RoundKey: " + bytesToHex(roundKey));
cipher = XORBytes(cipher, roundKey);
//System.out.println("CIPHER: " + bytesToHex(cipher));
}
/* Round 10*/
//System.out.println("Round 10");
cipher = subBytes(cipher);
//System.out.println("SubBytes: " + bytesToHex(cipher));
cipher = shiftRows(cipher);
//System.out.println("ShiftRows: " + bytesToHex(cipher));
roundKey = getRoundKey(10);
//System.out.println("RoundKey: " + bytesToHex(roundKey));
cipher = XORBytes(cipher, roundKey);
//System.out.println("CIPHER: " + bytesToHex(cipher));
return cipher;
}
public byte[] decrypt(byte[] cipher, byte[] key) throws Exception {
byte[] plainText = new byte[BLOCK_LENGTH];
this.word = expandKey(key);
byte[] roundKey = getRoundKey(10);
/* Round 0 */
plainText = XORBytes(cipher, roundKey);
/* Rounds 1 to 9*/
for (int i = 9 ; i > 0 ; i--) {
plainText = inverseShiftRows(plainText);
plainText = inverseSubBytes(plainText);
roundKey = getRoundKey(i);
plainText = XORBytes(plainText, roundKey);
plainText = inverseMixColumns(plainText);
}
/* Round 10*/
plainText = inverseShiftRows(plainText);
plainText = inverseSubBytes(plainText);
roundKey = getRoundKey(0);
plainText = XORBytes(plainText, roundKey);
return plainText;
}
public static void main(String[] args) throws Exception {
AES aes = new AES();
byte[] plainText = aes.hexStringToByteArray("0123456789abcdeffedcba9876543210");
System.out.println("PLAIN TEXT: " + bytesToHex(plainText));
byte[] key = aes.hexStringToByteArray("0f1571c947d9e8590cb7add6af7f6798");
System.out.println("KEY: " + bytesToHex(key));
byte[] cipher = aes.encrypt(plainText, key);
System.out.println("CIPHER TEXT: " + bytesToHex(cipher));
plainText = aes.decrypt(cipher, key);
System.out.println("DECRYPTED CIPHER TEXT: " + bytesToHex(plainText));
}
}
</pre>
<b><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Word.java</span></b>
<br />
<br />
<pre class="java" name="code">
public class Word {
private byte[] word = null;
public Word() {
word = new byte[4];
}
public Word(byte k0, byte k1, byte k2, byte k3) {
this();
word[0] = k0;
word[1] = k1;
word[2] = k2;
word[3] = k3;
}
public byte[] getWord() {
return word;
}
public void setWord(byte[] word) {
this.word = word;
}
public static byte[] wordToBytes(Word word) {
return word.getWord();
}
public static byte[] wordsToBytes(Word[] words) {
byte[] out = new byte[4 * words.length];
for (int i = 0 ; i < words.length ; i++) {
byte[] temp = words[i].getWord();
out[4*i] = temp[0];
out[4*i+1] = temp[1];
out[4*i+2] = temp[2];
out[4*i+3] = temp[3];
}
return out;
}
public void rotWord() {
byte[] temp = this.getWord();
byte[] newWord = new byte[4];
newWord[0] = temp[1];
newWord[1] = temp[2];
newWord[2] = temp[3];
newWord[3] = temp[0];
this.setWord(newWord);
}
public void subWord() {
byte[] in = this.getWord();
byte[] out = new byte[4];
for (int i = 0 ; i < 4 ; i++) {
byte a = in[i];
int row = (a >> 4) & 0x000F;
int col = a & 0x000F;
out[i] = (byte) AES.sBox[row * 16 + col];
}
for (int i = 0 ; i < 4 ; i++) {
this.word[i] = out[i];
}
}
public static Word XORWords(Word word1, Word word2) {
Word outWord = new Word();
byte[] in1 = word1.getWord();
byte[] in2 = word2.getWord();
byte[] out = new byte[4];
for (int i = 0 ; i < 4 ; i++) {
out[i] = (byte)((in1[i] ^ in2[i]) & 0xff);
}
outWord.setWord(out);
return outWord;
}
public String toString() {
return AES.bytesToHex(this.getWord());
}
}
</pre>
<b>Output</b><br />
<br />
<span style="font-family: Courier New, Courier, monospace;">PLAIN TEXT: 0123456789ABCDEFFEDCBA9876543210</span><br />
<span style="font-family: Courier New, Courier, monospace;">KEY: 0F1571C947D9E8590CB7ADD6AF7F6798</span><br />
<span style="font-family: Courier New, Courier, monospace;">CIPHER TEXT: FF0B844A0853BF7C6934AB4364148FB9</span><br />
<span style="font-family: Courier New, Courier, monospace;">DECRYPTED CIPHER TEXT: 0123456789ABCDEFFEDCBA9876543210</span><br />
<div>
<br /></div>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-80834286559195812992014-06-20T00:12:00.000+05:302014-06-20T01:10:27.982+05:30DES Implementation In Java<b><br /></b>
<b><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">DES.java</span></b>
<br />
<pre class="java" name="code">
public class DES {
/* Initial Permutation */
static final int[] IP = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
/* Inverse Initial Permutation */
static final int[] IIP = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/* Expansion Permutation */
static final int[] E = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/* Permutation Function */
static final int[] P = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/* S-Boxes*/
static final int[] S1 = {
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
};
static final int[] S2 = {
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
};
static final int[] S3 = {
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
};
static final int[] S4 = {
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
};
static final int[] S5 = {
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
};
static final int[] S6 = {
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
};
static final int[] S7 = {
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
};
static final int[] S8 = {
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
};
/* Permuted Choice One */
static final int[] PC1 = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
/* Permuted Choice Two */
static final int[] PC2 = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
/* Schedule of Left Shifts */
static final int[] SHIFTS = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
public DES() {
}
private byte[] performXOR(byte[] one, byte[] two) {
byte[] result = new byte[one.length];
for (int i = 0 ; i < one.length ; i++) {
result[i] = (byte) (one[i] ^ two[i]);
}
return result;
}
private byte[] permute(byte[] input, int[] mapping) {
int byteCount = 1 + (mapping.length - 1) / 8;
byte[] output = new byte[byteCount];
int pos;
for (int i = 0 ; i < mapping.length ; i++) {
pos = mapping[i] - 1;
int value = getBitFromArray(input, pos);
setBitInArray(output, i, value);
}
return output;
}
private int getBitFromArray(byte[] array, int pos) {
int value;
int bytePos = pos / 8;
int bitPos = pos % 8;
value = (array[bytePos] >> (8 - (bitPos + 1))) & 0x0001;
/* eg: right shift selected byte 5 times to get 3rd bit
* (bitPos = 2) at rightmost position and
* then AND with 0x0001*/
return value;
}
private void setBitInArray(byte[] input, int pos, int value) {
int bytePos = pos / 8;
int bitPos = pos % 8;
byte old = input[bytePos];
old = (byte) (((0xFF7F >> bitPos) & old) & 0x00FF);
byte newByte = (byte) ((value << (8 - (bitPos + 1))) | old);
input[bytePos] = newByte;
}
private byte[] hexStringToByteArray(String string) {
int length = string.length();
int n = (int)Math.ceil((length + 1) / 2);
byte[] result = new byte[n];
for (int i = length - 1; i >= 0 ; i -= 2) {
if (i == 0) {
result[i / 2] = (byte) ((Character.digit('0', 16) << 4)
+ Character.digit(string.charAt(i), 16));
} else {
result[i / 2] = (byte) ((Character.digit(string.charAt(i - 1), 16) << 4)
+ Character.digit(string.charAt(i), 16));
}
}
return result;
}
private void printBytes(byte[] input) {
for (int i = 0 ; i < input.length; i++) {
System.out.print(byteToBits(input[i]) + " ");
}
System.out.println();
}
private String byteToBits(byte b) {
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 8 ; i++)
buffer.append((int)(b >> (8-(i+1)) & 0x0001));
return buffer.toString();
}
private byte[] getBits(byte[] input, int startPos, int length) {
int noOfBytes = (length-1)/8 + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < length ; i++) {
int value = getBitFromArray(input, startPos + i);
setBitInArray(output, i, value);
}
return output;
}
private byte[] rotateLeft(byte[] input, int step, int length) {
int noOfBytes = (length - 1) / 8 + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < length ; i++) {
int value = getBitFromArray(input, (i + step) % length);
setBitInArray(output, i, value);
}
return output;
}
private byte[] concatBits(byte[] one, int oneLength,
byte[] two, int twoLength) {
int noOfBytes = (oneLength + twoLength - 1) / 8 + 1;
byte[] output = new byte[noOfBytes];
int i = 0, j = 0;
for (; i < oneLength ; i++) {
int value = getBitFromArray(one, i);
setBitInArray(output, j, value);
j++;
}
for (i = 0 ; i < twoLength ; i++) {
int value = getBitFromArray(two, i);
setBitInArray(output, j, value);
j++;
}
return output;
}
private byte[][] getSubKeys(byte[] masterKey) {
int noOfSubKeys = SHIFTS.length;
int keySize = PC1.length;
byte[] key = permute(masterKey, PC1);
byte[][] subKeys = new byte[noOfSubKeys][keySize];
byte[] leftHalf = getBits(key, 0, keySize/2);
byte[] rightHalf = getBits(key, keySize/2, keySize/2);
for (int i = 0 ; i < noOfSubKeys ; i++) {
leftHalf = rotateLeft(leftHalf, SHIFTS[i], keySize/2);
rightHalf = rotateLeft(rightHalf, SHIFTS[i], keySize/2);
byte[] subKey = concatBits(leftHalf, keySize/2, rightHalf, keySize/2);
subKeys[i] = permute(subKey, PC2);
}
return subKeys;
}
public byte[] crypt(byte[] message, byte[] key, String operation) {
if (message.length < 8) {
System.out.println("Message should be atleast 64 bits");
System.exit(1);
}
if (key.length != 8) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
int length = message.length;
int n = (length + 7)/8 * 8;
byte[] cipher = new byte[n];
if (length == 8) {
return cryptText(message, key, operation);
}
int i = 0;
int k = 0;
while (i < length) {
byte[] block = new byte[8];
byte[] result = new byte[8];
int j = 0;
for (; j < 8 && i < length; j++, i++) {
block[j] = message[i];
}
while (j < 8) {
block[j++] = 0x00;
}
System.out.println("BLOCK: ");
printBytes(block);
result = cryptText(block, key, operation);
System.out.println("RESULT: ");
printBytes(result);
for (j = 0 ; j < 8 && k < cipher.length; j++, k++) {
cipher[k] = result[j];
}
}
return cipher;
}
public byte[] cryptText(byte[] message, byte[] key, String operation) {
if (message.length != 8) {
System.out.println("Message should be 64 bits");
System.exit(1);
}
if (key.length != 8) {
System.out.println("Key should be 64 bits");
System.exit(1);
}
byte[] result = null;
int blockSize = IP.length;
byte[][] subKeys = getSubKeys(key);
int noOfRounds = subKeys.length;
/**
* Initial Permutation
*/
message = permute(message, IP);
/**
* Split message into two halves
*/
byte[] leftHalf = getBits(message, 0, blockSize/2);
byte[] rightHalf = getBits(message, blockSize/2, blockSize/2);
for (int i = 0 ; i < noOfRounds ; i++) {
byte[] temp = rightHalf;
/**
* Expansion
*/
rightHalf = permute(rightHalf, E);
/**
* XOR rightHalf with roundKey
*/
byte[] roundKey = null;
if (operation.equalsIgnoreCase("encrypt")) {
roundKey = subKeys[i];
} else if (operation.equalsIgnoreCase("decrypt")) {
roundKey = subKeys[noOfRounds - i - 1];
} else {
System.out.println("Unsupported operation");
System.exit(0);
}
rightHalf = performXOR(rightHalf, roundKey);
/**
* S-Box
*/
rightHalf = sBox(rightHalf);
/**
* Permutation
*/
rightHalf = permute(rightHalf, P);
/**
* XOR rightHalf with leftHalf
*/
rightHalf = performXOR(rightHalf, leftHalf);
/**
* L(i) = R(i-1)
*/
leftHalf = temp;
}
/**
* 32 bit swap
*/
byte[] concatHalves = concatBits(rightHalf, blockSize/2, leftHalf, blockSize/2);
/**
* Inverse Initial Permutation
*/
result = permute(concatHalves, IIP);
return result;
}
private byte[] sBox(byte[] input) {
/**
* Split input to 6-bit blocks
*/
input = split(input,6);
byte[] output = new byte[input.length/2];
int leftHalf = 0;
for (int i = 0; i < input.length ; i++) {
byte block = input[i];
/**
* row - first and last bits
* column - 4 bits in the middle
*/
int row = 2 * (block >> 7 & 0x0001) + (block >> 2 & 0x0001);
int col = block >> 3 & 0x000F;
int[] selectedSBox = getSBox(i);
int rightHalf = selectedSBox[16 * row + col];
if (i % 2 == 0) {
leftHalf = rightHalf;
} else {
output[i/2] = (byte) (16 * leftHalf + rightHalf);
leftHalf = 0;
}
}
return output;
}
private int[] getSBox(int i) {
switch (i) {
case 0: return S1;
case 1: return S2;
case 2: return S3;
case 3: return S4;
case 4: return S5;
case 5: return S6;
case 6: return S7;
case 7: return S8;
default: return null;
}
}
private byte[] split(byte[] input, int length) {
int noOfBytes = (8 * input.length - 1) / length + 1;
byte[] output = new byte[noOfBytes];
for (int i = 0 ; i < noOfBytes ; i++) {
for (int j = 0; j < length ; j++) {
int value = getBitFromArray(input, length * i + j);
setBitInArray(output, 8 * i + j, value);
}
}
return output;
}
public static void main(String[] args) {
DES des = new DES();
byte[] message = des.hexStringToByteArray("123456789ABCDEF");
System.out.println("PLAIN TEXT:");
des.printBytes(message);
byte[] key = des.hexStringToByteArray("133457799BBCDFF1");
System.out.println("KEY:");
des.printBytes(key);
byte[] cipher = des.crypt(message, key, "encrypt");
System.out.println("CIPHER TEXT:");
des.printBytes(cipher);
byte[] result = des.crypt(cipher, key, "decrypt");
System.out.println("DECRYPTED TEXT:");
des.printBytes(result);
}
}
</pre>
<br />
<b><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Output </span></b><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~$ javac DES.java </span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~$ java DES </span><br />
<span style="font-family: Courier New, Courier, monospace;">PLAIN TEXT: </span><br />
<span style="font-family: Courier New, Courier, monospace;">00000001 00100011 01000101 01100111 10001001 10101011 11001101 11101111 </span><br />
<span style="font-family: Courier New, Courier, monospace;">KEY: </span><br />
<span style="font-family: Courier New, Courier, monospace;">00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001 </span><br />
<span style="font-family: Courier New, Courier, monospace;">CIPHER TEXT: </span><br />
<span style="font-family: Courier New, Courier, monospace;">10000101 11101000 00010011 01010100 00001111 00001010 10110100 00000101 </span><br />
<span style="font-family: Courier New, Courier, monospace;">DECRYPTED TEXT: </span><br />
<span style="font-family: Courier New, Courier, monospace;">00000001 00100011 01000101 01100111 10001001 10101011 11001101 11101111</span><br />
<span style="font-family: Courier New, Courier, monospace;">dhanoopbhaskar@dhanoop-laptop:~$
</span>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-64726260281366712062014-05-19T23:23:00.001+05:302020-11-01T10:02:02.746+05:30Total Views Crossed 50K !! Thanks for your support !!<blockquote>
<br />
Today the total views crossed 50K :-)<br />
Thanks for your support!
</blockquote>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-68287461842644897952014-04-26T17:51:00.000+05:302014-04-26T18:06:06.100+05:30Java - Common Problems (and Their Solutions)<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Original Link: </b></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><a href="http://docs.oracle.com/javase/tutorial/getStarted/problems/"><span style="color: black;">http://docs.oracle.com/javase/tutorial/getStarted/problems/</span></a>
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><b><br /></b></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Check the license before redistribution:</b>
<a href="http://docs.oracle.com/javase/tutorial/information/license.html"><span style="color: black;">http://docs.oracle.com/javase/tutorial/information/license.html</span></a></span>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com0tag:blogger.com,1999:blog-1188765056128955958.post-59218430951860386012014-04-09T20:00:00.001+05:302014-04-09T20:03:00.344+05:30Java - Encryption and Decryption of an Image Using Another Image (Blowfish Algorithm)
<br />
<pre class="java" name="code">
/* EncryptFile.java */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
*
* @author dhanoopbhaskar
*/
public class EncryptFile {
SecretKey secretKey = null;
Cipher cipher = null;
String filePath = null;
public EncryptFile(String filePath) {
this.filePath = filePath;
try {
/**
* Create a Blowfish key
*/
byte[] password = getPasswordFromFile(filePath);
if (password == null) {
System.out.println("Unable to read the password file!");
System.exit(0);
}
secretKey = new SecretKeySpec(password, "Blowfish");
/**
* Create an instance of cipher mentioning the name of algorithm
* - Blowfish
*/
cipher = Cipher.getInstance("Blowfish");
} catch (NoSuchPaddingException ex) {
System.out.println(ex);
} catch (NoSuchAlgorithmException ex) {
System.out.println(ex);
}
}
/**
*
* @param filePath
* @return password
*
* Encrypts the file in srcPath and creates a file in destPath
*/
private byte[] getPasswordFromFile(String filePath) {
File file = new File(filePath);
InputStream inStream;
/**
* maximum allowable key size for blowfish is 56 bytes,
* but java supports only upto 16 bytes.
*/
byte[] buffer = new byte[16];
try {
inStream = new FileInputStream(file);
int len = inStream.read(buffer);
if (len <= 0) buffer = null;
} catch (FileNotFoundException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
return buffer;
}
public static void main(String[] args) {
String fileToEncrypt = "fileToEncrypt.jpg";
String encryptedFile = "encryptedFile.jpg";
String decryptedFile = "decryptedFile.jpg";
String directoryPath = "/home/dhanoopbhaskar/Desktop/blowfish/";
String passwordFile = "password.jpg";
EncryptFile encryptFile = new EncryptFile(directoryPath + passwordFile);
System.out.println("Starting Encryption...");
encryptFile.encrypt(directoryPath + fileToEncrypt,
directoryPath + encryptedFile);
System.out.println("Encryption completed...");
encryptFile = new EncryptFile(directoryPath + passwordFile);
System.out.println("Starting Decryption...");
encryptFile.decrypt(directoryPath + encryptedFile,
directoryPath + decryptedFile);
System.out.println("Decryption completed...");
}
/**
*
* @param srcPath
* @param destPath
*
* Encrypts the file in srcPath and creates a file in destPath
*/
private void encrypt(String srcPath, String destPath) {
File rawFile = new File(srcPath);
File encryptedFile = new File(destPath);
InputStream inStream = null;
OutputStream outStream = null;
try {
/**
* Initialize the cipher for encryption
*/
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
/**
* Initialize input and output streams
*/
inStream = new FileInputStream(rawFile);
outStream = new FileOutputStream(encryptedFile);
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) > 0) {
outStream.write(cipher.update(buffer, 0, len));
outStream.flush();
}
outStream.write(cipher.doFinal());
inStream.close();
outStream.close();
} catch (IllegalBlockSizeException ex) {
System.out.println(ex);
} catch (BadPaddingException ex) {
System.out.println(ex);
} catch (InvalidKeyException ex) {
System.out.println(ex);
} catch (FileNotFoundException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
}
/**
*
* @param srcPath
* @param destPath
*
* Decrypts the file in srcPath and creates a file in destPath
*/
private void decrypt(String srcPath, String destPath) {
File encryptedFile = new File(srcPath);
File decryptedFile = new File(destPath);
InputStream inStream = null;
OutputStream outStream = null;
try {
/**
* Initialize the cipher for decryption
*/
cipher.init(Cipher.DECRYPT_MODE, secretKey);
/**
* Initialize input and output streams
*/
inStream = new FileInputStream(encryptedFile);
outStream = new FileOutputStream(decryptedFile);
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) > 0) {
outStream.write(cipher.update(buffer, 0, len));
outStream.flush();
}
outStream.write(cipher.doFinal());
inStream.close();
outStream.close();
} catch (IllegalBlockSizeException ex) {
System.out.println(ex);
} catch (BadPaddingException ex) {
System.out.println(ex);
} catch (InvalidKeyException ex) {
System.out.println(ex);
} catch (FileNotFoundException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
}
}
</pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjORo8H5nHPyLc63ZAkZTtTAnhRQALVvzqdni2y86zsb9ZDbHhbIVEAYfh_G1fluXOUeDPpNSUJVA3rgiW03wtLNeqVdym_xGE_wNYi-avdUOojHSPjJsSIwE4VbVWVItYVEDiXc4U0Rh4/s1600/Screenshot-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjORo8H5nHPyLc63ZAkZTtTAnhRQALVvzqdni2y86zsb9ZDbHhbIVEAYfh_G1fluXOUeDPpNSUJVA3rgiW03wtLNeqVdym_xGE_wNYi-avdUOojHSPjJsSIwE4VbVWVItYVEDiXc4U0Rh4/s320/Screenshot-2.png" /></a></div>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com2tag:blogger.com,1999:blog-1188765056128955958.post-71512217537900727862014-04-05T22:22:00.000+05:302014-04-05T22:32:54.624+05:30Java - Encryption and Decryption of an Image Using Blowfish Algorithm (using password)<blockquote>
</blockquote>
<br />
<pre class="java" name="code">
package com.java.blowfish;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
*
* @author dhanoopbhaskar
*/
public class EncryptFile {
KeyGenerator keyGenerator = null;
SecretKey secretKey = null;
Cipher cipher = null;
String masterPassword = null;
public EncryptFile(String masterPassword) {
this.masterPassword = masterPassword;
try {
/**
* Create a Blowfish key
*/
keyGenerator = KeyGenerator.getInstance("Blowfish");
secretKey = new SecretKeySpec(masterPassword.getBytes(), "Blowfish");
/**
* Create an instance of cipher mentioning the name of algorithm
* - Blowfish
*/
cipher = Cipher.getInstance("Blowfish");
} catch (NoSuchPaddingException ex) {
System.out.println(ex);
} catch (NoSuchAlgorithmException ex) {
System.out.println(ex);
}
}
public static void main(String[] args) {
String fileToEncrypt = "fileToEncrypt.jpg";
String encryptedFile = "encryptedFile.jpg";
String decryptedFile = "decryptedFile.jpg";
String directoryPath = "/home/dhanoopbhaskar/Desktop/blowfish/";
EncryptFile encryptFile = new EncryptFile("thisismypassword");
System.out.println("Starting Encryption...");
encryptFile.encrypt(directoryPath + fileToEncrypt,
directoryPath + encryptedFile);
System.out.println("Encryption completed...");
encryptFile = new EncryptFile("thisismypassword");
System.out.println("Starting Decryption...");
encryptFile.decrypt(directoryPath + encryptedFile,
directoryPath + decryptedFile);
System.out.println("Decryption completed...");
}
/**
*
* @param srcPath
* @param destPath
*
* Encrypts the file in srcPath and creates a file in destPath
*/
private void encrypt(String srcPath, String destPath) {
File rawFile = new File(srcPath);
File encryptedFile = new File(destPath);
InputStream inStream = null;
OutputStream outStream = null;
try {
/**
* Initialize the cipher for encryption
*/
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
/**
* Initialize input and output streams
*/
inStream = new FileInputStream(rawFile);
outStream = new FileOutputStream(encryptedFile);
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) > 0) {
outStream.write(cipher.update(buffer, 0, len));
outStream.flush();
}
outStream.write(cipher.doFinal());
inStream.close();
outStream.close();
} catch (IllegalBlockSizeException ex) {
System.out.println(ex);
} catch (BadPaddingException ex) {
System.out.println(ex);
} catch (InvalidKeyException ex) {
System.out.println(ex);
} catch (FileNotFoundException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
}
/**
*
* @param srcPath
* @param destPath
*
* Decrypts the file in srcPath and creates a file in destPath
*/
private void decrypt(String srcPath, String destPath) {
File encryptedFile = new File(srcPath);
File decryptedFile = new File(destPath);
InputStream inStream = null;
OutputStream outStream = null;
try {
/**
* Initialize the cipher for decryption
*/
cipher.init(Cipher.DECRYPT_MODE, secretKey);
/**
* Initialize input and output streams
*/
inStream = new FileInputStream(encryptedFile);
outStream = new FileOutputStream(decryptedFile);
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) > 0) {
outStream.write(cipher.update(buffer, 0, len));
outStream.flush();
}
outStream.write(cipher.doFinal());
inStream.close();
outStream.close();
} catch (IllegalBlockSizeException ex) {
System.out.println(ex);
} catch (BadPaddingException ex) {
System.out.println(ex);
} catch (InvalidKeyException ex) {
System.out.println(ex);
} catch (FileNotFoundException ex) {
System.out.println(ex);
} catch (IOException ex) {
System.out.println(ex);
}
}
}
</pre>
<br/>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7AXT_O7mMOAn7pjgL348nozsUWTS4t0DGtJukHjtG-hzjsGzYNwJ1WGvU1iSDv3i9xcz4f2Toqlisngd87GqTdAb2pfgTOkDWia3MYiGqClmX1Ryaq7avcq0lZdAFod66nDUTTArCApg/s1600/blog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7AXT_O7mMOAn7pjgL348nozsUWTS4t0DGtJukHjtG-hzjsGzYNwJ1WGvU1iSDv3i9xcz4f2Toqlisngd87GqTdAb2pfgTOkDWia3MYiGqClmX1Ryaq7avcq0lZdAFod66nDUTTArCApg/s320/blog.png" /></a></div>
Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com2tag:blogger.com,1999:blog-1188765056128955958.post-53654382696093218672014-02-13T23:06:00.001+05:302014-02-19T21:24:13.983+05:30A simple HTTP client and a server in C<i><span style="font-family: Arial, Helvetica, sans-serif;">The HTTP server sends the files requested by the client, if it is available at the server. The HTTP client uses GET method for requesting files from the server. Only .html, .txt and .pdf files are implemented. On receiving the file, the client program opens it using firefox or gedit or acrobat reader, as per the file type. Note that the given programs were done in Linux (Debian) environment. </span></i><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b><u>httpserver.c
</u></b></span><br />
<pre class="c" name="code">
/**httpserver.c**/
#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include"time.h"
#include"dirent.h"
#include"netdb.h"
#define BUF_SIZE 1024
#define CLADDR_LEN 100
int createSocket(char * host, int port);
int listenForRequest(int sockfd);
char * getFileType(char * file);
int main(int argc, char **argv) {
DIR * dirptr;
FILE * fileptr;
time_t timenow;
struct tm * timeinfo;
time (&timenow);
timeinfo = localtime(&timenow);
char * header, * request, * path, * newpath, * host;
char * dir, * temp;
int port, sockfd, connfd;
char get[3], http[9];
char filepath[BUF_SIZE];
char http_not_found[] = "HTTP/1.0 404 Not Found\n";
char http_ok[] = "HTTP/1.0 200 OK\n";
char buffer[BUF_SIZE];
char * contentType;
if (argc != 4) {
printf("usage: [host] [directory] [portnumber]\n");
exit(1);
}
header = (char*)malloc(BUF_SIZE*sizeof(char));
request = (char*)malloc(BUF_SIZE*sizeof(char));
path = (char*)malloc(BUF_SIZE*sizeof(char));
newpath = (char*)malloc(BUF_SIZE*sizeof(char));
host = argv[1];
dir = argv[2];
port = atoi(argv[3]);
if ((dirptr = opendir(dir)) == NULL) {
printf("Directory Not Found!\n");
exit(1);
}
sockfd = createSocket(host, port);
for (;;) {
printf("--------------------------------------------------------\n");
printf("Waiting for a connection...\n");
connfd = listenForRequest(sockfd);
//gets the request from the connection
recv(connfd, request, 100, 0);
printf("Processing request...\n");
//parses request
sscanf(request, "%s %s %s", get, path, http);
newpath = path + 1; //ignores the first slash
sprintf(filepath,"%s/%s", dir, newpath);
contentType = getFileType(newpath);
sprintf(header, "Date: %sHostname: %s:%d\nLocation: %s\nContent-Type: %s\n\n", asctime(timeinfo), host, port, newpath, contentType);
if ((fileptr = fopen(filepath, "r")) == NULL ) {
printf("File not found!\n");
send(connfd, http_not_found, strlen(http_not_found), 0); //sends HTTP 404
} else {
printf("Sending the file...\n");
send(connfd, http_ok, strlen(http_ok), 0); //sends HTTP 200 OK
recv(connfd, buffer, BUF_SIZE, 0);
if ((temp = strstr(buffer, "OK")) == NULL) {
printf("Operation aborted by the user!\n");
break;
}
send(connfd, header, strlen(header), 0); //sends the header
recv(connfd, buffer, BUF_SIZE, 0);
if ((temp = strstr(buffer, "OK")) == NULL) {
printf("Operation aborted by the user!\n");
break;
}
memset(&buffer, 0, sizeof(buffer));
while (!feof(fileptr)) { //sends the file
fread(&buffer, sizeof(buffer), 1, fileptr);
send(connfd, buffer, sizeof(buffer), 0);
memset(&buffer, 0, sizeof(buffer));
}
printf("File sent...\n");
}
printf("Processing completed...\n");
close(connfd);
}
close(sockfd);
free(header);
free(request);
free(path);
free(newpath);
return 0;
}
int createSocket(char * host, int port) {
int sockfd;
struct sockaddr_in addr;
struct hostent * host_ent;
char * hostAddr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons((short)port);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
printf("Error binding socket to port!\n");
exit(1);
}
printf("Binding done...\n");
return sockfd;
}
int listenForRequest(int sockfd) {
int conn;
char hostip[32];
struct sockaddr_in addr;
struct hostent * host;
struct in_addr inAddr;
int len;
addr.sin_family = AF_INET;
listen(sockfd, 5); //maximum 5 connections
len = sizeof(addr);
if ((conn = accept(sockfd, (struct sockaddr *)&addr, &len)) < 0) {
printf("Error accepting connection!\n");
exit(1);
}
printf("Connection accepted...\n");
inet_ntop(AF_INET, &(addr.sin_addr), hostip, 32);
inet_pton(AF_INET, hostip, &inAddr);
host = gethostbyaddr(&inAddr, sizeof(inAddr), AF_INET);
printf("---Connection received from: %s [IP= %s]---\n", host->h_name, hostip);
return conn;
}
char * getFileType(char * file) {
char * temp;
if ((temp = strstr(file, ".html")) != NULL) {
return "text/html";
} else if ((temp = strstr(file, ".pdf")) != NULL) {
return "application/pdf";
} else if ((temp = strstr(file, ".txt")) != NULL) {
return "text/html";
}
}
</pre>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b><u><br /></u></b></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b><u>httpclient.c
</u></b></span><br />
<pre class="c" name="code">
/**httpclient.c**/
#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include"netdb.h"
#define BUF_SIZE 1024
int get_request(char * url, char * port);
int isValidIP(char * ip);
int parseHeader(char * header);
char * splitKeyValue(char * line, int index);
void openFile();
FILE * fileptr;
char keys[][25] = {"Date: ", "Hostname: ", "Location: ", "Content-Type: "};
char status[4] = {0, 0, 0, 0};
char contentFileType[100];
char path[1000];
int main(int argc, char**argv) {
struct sockaddr_in addr, cl_addr;
int sockfd, ret;
struct hostent * server;
char * url, * temp;
int portNumber;
char * fileName;
char status_ok[] = "OK";
char buffer[BUF_SIZE];
char http_not_found[] = "HTTP/1.0 404 Not Found";
char http_ok[] = "HTTP/1.0 200 OK";
char location[] = "Location: ";
char contentType[] = "Content-Type: ";
int sPos, ePos;
if (argc < 3) {
printf("usage: [URL] [port number]\n");
exit(1);
}
url = argv[1];
portNumber = atoi(argv[2]);
//checking the protocol specified
if ((temp = strstr(url, "http://")) != NULL) {
url = url + 7;
} else if ((temp = strstr(url, "https://")) != NULL) {
url = url + 8;
}
//checking the port number
if (portNumber > 65536 || portNumber < 0) {
printf("Invalid Port Number!");
exit(1);
}
sockfd = get_request(url, argv[2]);
memset(&buffer, 0, sizeof(buffer));
ret = recv(sockfd, buffer, BUF_SIZE, 0);
if (ret < 0) {
printf("Error receiving HTTP status!\n");
} else {
printf("%s\n", buffer);
if ((temp = strstr(buffer, http_ok)) != NULL) {
send(sockfd, status_ok, strlen(status_ok), 0);
} else {
close(sockfd);
return 0;
}
}
memset(&buffer, 0, sizeof(buffer));
ret = recv(sockfd, buffer, BUF_SIZE, 0);
if (ret < 0) {
printf("Error receiving HTTP header!\n");
} else {
printf("%s\n", buffer);
if (parseHeader(buffer) == 0) {
send(sockfd, status_ok, strlen(status_ok), 0);
} else {
printf("Error in HTTP header!\n");
close(sockfd);
return 0;
}
}
//printf("file: [%s]\n", fileName);
fileptr = fopen(path, "w");
if (fileptr == NULL) {
printf("Error opening file!\n");
close(sockfd);
return 0;
}
memset(&buffer, 0, sizeof(buffer));
while (recv(sockfd, buffer, BUF_SIZE, 0) > 0) { //receives the file
if ((strstr(contentFileType, "text/html")) != NULL) {
fprintf(fileptr, "%s", buffer);
} else {
fwrite(&buffer, sizeof(buffer), 1, fileptr);
}
memset(&buffer, 0, sizeof(buffer));
}
fclose(fileptr);
close(sockfd);
openFile();
return 0;
}
int get_request(char * url, char * port) {
int sockfd, bindfd;
char * ptr, * host;
char getrequest[1024];
struct sockaddr_in addr;
if (isValidIP(url)) { //when an IP address is given
sprintf(getrequest, "GET / HTTP/1.0\nHOST: %s\n\n", url);
} else { //when a host name is given
if ((ptr = strstr(url, "/")) == NULL) {
//when hostname does not contain a slash
sprintf(getrequest, "GET / HTTP/1.0\nHOST: %s\n\n", url);
} else {
//when hostname contains a slash, it is a path to file
strcpy(path, ptr);
host = strtok(url, "/");
sprintf(getrequest, "GET %s HTTP/1.0\nHOST: %s\n\n", path, url);
}
}
// creates a socket to the host
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(url);
addr.sin_port = htons(atoi(port));
if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) {
printf("Connection Error!\n");
exit(1);
}
printf("Connection successful...\n\n\n");
ptr = strtok(path, "/");
strcpy(path, ptr);
//printf("path=%s\n", path);
//fileptr = fopen(path, "w");
//strcpy(fileName, path);
//sprintf(fileName, "%s", path);
//int optval = 1;
//setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
// writes the HTTP GET Request to the sockfd
write(sockfd, getrequest, strlen(getrequest));
return sockfd;
}
int isValidIP(char * ip) {
struct sockaddr_in addr;
int valid = inet_pton(AF_INET, ip, &(addr.sin_addr));
return valid != 0;
}
int parseHeader(char * header) {
//"Date: %sHostname: %s:%d\nLocation: %s\nContent-Type: %s\n\n"
char * line, * key, * value;
char temp[100];
int i = 0;
line = strtok(header, "\n");
while (line != NULL) {
//printf("%s\n", line);
strcpy(temp, line);
value = splitKeyValue(line, i);
if (i == 3) {
strcpy(contentFileType, value);
}
//printf("value=%s\n", value);
line = strtok(NULL, "\n");
i++;
}
for (i = 0; i < 4; i++) {
if (status[i] == 0) return 1;
//printf("status[%d]=%d\n", i, status[i]);
}
return 0;
}
char * splitKeyValue(char * line, int index) {
char * temp;
if ((temp = strstr(line, keys[index])) != NULL) {
temp = temp + strlen(keys[index]);
status[index] = 1;
}
return temp;
}
void openFile() {
char * temp;
char command[100];
char fileName[1000];
strcpy(fileName, path);
//printf("File Name: %s\n", fileName);
//printf("Content Type: %s\n", contentFileType);
if ((temp = strstr(contentFileType, "text/html")) != NULL) {
if ((temp = strstr(fileName, ".txt")) != NULL) {
sprintf(command, "gedit %s", fileName);
} else {
sprintf(command, "firefox %s", fileName);
}
system(command);
} else if ((temp = strstr(contentFileType, "application/pdf")) != NULL) {
sprintf(command, "acroread %s", fileName);
system(command);
} else {
printf("The filetype %s is not supported. Failed to open %s!\n", contentFileType, fileName);
}
}
</pre>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><u>Execution:</u> </span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">(terminal 1) </span><br />
<span style="font-family: Courier New, Courier, monospace;">gcc httpserver.c -o server </span><br />
<span style="font-family: Courier New, Courier, monospace;">./server 'www.dhanoop.com' '/home/dhanoopbhaskar/coding/http/dir/' 4444 </span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">(terminal 2) </span><br />
<span style="font-family: Courier New, Courier, monospace;">gcc httpclient.c -o client </span><br />
<span style="font-family: Courier New, Courier, monospace;">./client '192.168.0.6/abc.txt' 4444 </span><br />
<span style="font-family: Courier New, Courier, monospace;">./client '192.168.0.6/abc.html' 4444 </span><br />
<span style="font-family: Courier New, Courier, monospace;">./client '192.168.0.6/abc.pdf' 4444</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<i><span style="font-family: Arial, Helvetica, sans-serif;">NB: The requested files abc.txt, abc.html and abc.pdf should be present in the path '/home/dhanoopbhaskar/coding/http/dir/' (or whatever is given while running server).</span></i>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com6tag:blogger.com,1999:blog-1188765056128955958.post-32623835213946673852014-01-22T20:26:00.001+05:302014-01-22T20:31:12.241+05:30A simple chat program in C (TCP)<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b><u>tcpserver.c
</u></b></span><br />
<pre class="c" name="code">
#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include"pthread.h"
#define PORT 4444
#define BUF_SIZE 2000
#define CLADDR_LEN 100
void * receiveMessage(void * socket) {
int sockfd, ret;
char buffer[BUF_SIZE];
sockfd = (int) socket;
memset(buffer, 0, BUF_SIZE);
for (;;) {
ret = recvfrom(sockfd, buffer, BUF_SIZE, 0, NULL, NULL);
if (ret < 0) {
printf("Error receiving data!\n");
} else {
printf("client: ");
fputs(buffer, stdout);
//printf("\n");
}
}
}
void main() {
struct sockaddr_in addr, cl_addr;
int sockfd, len, ret, newsockfd;
char buffer[BUF_SIZE];
pid_t childpid;
char clientAddr[CLADDR_LEN];
pthread_t rThread;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = PORT;
ret = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error binding!\n");
exit(1);
}
printf("Binding done...\n");
printf("Waiting for a connection...\n");
listen(sockfd, 5);
len = sizeof(cl_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cl_addr, &len);
if (newsockfd < 0) {
printf("Error accepting connection!\n");
exit(1);
}
inet_ntop(AF_INET, &(cl_addr.sin_addr), clientAddr, CLADDR_LEN);
printf("Connection accepted from %s...\n", clientAddr);
memset(buffer, 0, BUF_SIZE);
printf("Enter your messages one by one and press return key!\n");
//creating a new thread for receiving messages from the client
ret = pthread_create(&rThread, NULL, receiveMessage, (void *) newsockfd);
if (ret) {
printf("ERROR: Return Code from pthread_create() is %d\n", ret);
exit(1);
}
while (fgets(buffer, BUF_SIZE, stdin) != NULL) {
ret = sendto(newsockfd, buffer, BUF_SIZE, 0, (struct sockaddr *) &cl_addr, len);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
}
close(newsockfd);
close(sockfd);
pthread_exit(NULL);
return;
}
</pre>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b><u>tcpclient.c
</u></b></span><br />
<pre class="c" name="code">
#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include"netdb.h"
#include"pthread.h"
#define PORT 4444
#define BUF_SIZE 2000
void * receiveMessage(void * socket) {
int sockfd, ret;
char buffer[BUF_SIZE];
sockfd = (int) socket;
memset(buffer, 0, BUF_SIZE);
for (;;) {
ret = recvfrom(sockfd, buffer, BUF_SIZE, 0, NULL, NULL);
if (ret < 0) {
printf("Error receiving data!\n");
} else {
printf("server: ");
fputs(buffer, stdout);
//printf("\n");
}
}
}
int main(int argc, char**argv) {
struct sockaddr_in addr, cl_addr;
int sockfd, ret;
char buffer[BUF_SIZE];
char * serverAddr;
pthread_t rThread;
if (argc < 2) {
printf("usage: client < ip address >\n");
exit(1);
}
serverAddr = argv[1];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(serverAddr);
addr.sin_port = PORT;
ret = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error connecting to the server!\n");
exit(1);
}
printf("Connected to the server...\n");
memset(buffer, 0, BUF_SIZE);
printf("Enter your messages one by one and press return key!\n");
//creating a new thread for receiving messages from the server
ret = pthread_create(&rThread, NULL, receiveMessage, (void *) sockfd);
if (ret) {
printf("ERROR: Return Code from pthread_create() is %d\n", ret);
exit(1);
}
while (fgets(buffer, BUF_SIZE, stdin) != NULL) {
ret = sendto(sockfd, buffer, BUF_SIZE, 0, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error sending data!\n\t-%s", buffer);
}
}
close(sockfd);
pthread_exit(NULL);
return 0;
}
</pre>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><u>terminal 1</u> </span><br />
<span style="font-family: Courier New, Courier, monospace;">gcc tcpserver.c -o server -pthread </span><br />
<span style="font-family: Courier New, Courier, monospace;">./server </span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><u>terminal 2</u> </span><br />
<span style="font-family: Courier New, Courier, monospace;">gcc tcpclient.c -o client -pthread </span><br />
<span style="font-family: Courier New, Courier, monospace;">./client 192.168.0.4
</span>Dhanoop Bhaskarhttp://www.blogger.com/profile/06123558027322013737noreply@blogger.com18