Archive for January, 2010
This post builds upon the ideas shown in this post to create a complete function that will do the follow:
- Accept a string input for the message
- Try to open twidroidpro to send this tweet
- If failed, try to open twidroid to send this tweet
- If failed, bring up a list of applications that can send this information
- Return a boolean indicating success of displaying the intent
Code
public boolean intentTwitter(String message){
// Boolean to show if we succeeded or not
// we assume we did until proven otherwise.
boolean success=true;
//Try twidroidpro first
Intent intent = new Intent("com.twidroidpro.SendTweet");
intent.putExtra("com.twidroidpro.extra.MESSAGE", message);
intent.setType("application/twitter");
try{
startActivityForResult(intent, 1);
}
catch(ActivityNotFoundException e){
success=false;
}
// Then twidroid if we failed
if (!success){
success=true;
intent = new Intent("com.twidroid.SendTweet");
intent.putExtra("com.twidroid.extra.MESSAGE", message);
intent.setType("application/twitter");
try{
startActivityForResult(intent, 1);
}
catch(ActivityNotFoundException e){
success=false;
}
}
//Then send general intent if we failed again
if (!success){
success=true;
try {
intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, d);
intent.setType("application/twitter");
startActivity(Intent.createChooser(intent, null));
} catch (ActivityNotFoundException e) {
success=false;
}
}
// return indicating if we were successful in bringing up an intent
// of some description
return success;
}
Example
Below is a screenshot from the wordcube (available on market) application using this function to make the application interact with twitter.
What’s next?
In a future post I will be demonstrating how to interact with the android market, this can be use in conjunction with something similar to above to try and run a program and if the program is not installed the user can be taken to the market to download a program.
A soundboard is a very simple application to make, and I was given the idea to make a counter-strike 1.6 version by a friend. It seemed like a good idea as no one had made one yet, and it’s quite hard to find something that hasn’t already been done before.
counter-strike 1.6 soundboard
The buttons are aligned in a grid view, with the buttons made transparent so that the background can be seen.

screenshot of counter-strike 1.6 soundboard

screenshot of counter-strike 1.6 soundboard
I am very pleased with the final look of the app, however it was getting poor reviews due to people wanting to save the sounds for use as a ringtone. To alleviate this problem I have updated the app to have this option as a context menu avaliable by long pressing on a button. This will then save the file on the sd card and update the mediastore to tell android a new ringtone and notification has been added.
The code to load a ringtone into android from an application is shown below. If you see any problems with this code, or have an improvements please let me know!
File k = new File(path, filename); ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath()); values.put(MediaStore.MediaColumns.TITLE, filesnames[pos]); values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav"); values.put(MediaStore.Audio.Media.ARTIST, "cssounds "); values.put(MediaStore.Audio.Media.IS_RINGTONE, true); values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true); values.put(MediaStore.Audio.Media.IS_ALARM, true); values.put(MediaStore.Audio.Media.IS_MUSIC, false); //Insert it into the database this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);
Ratings, reviews, feedback and feature requests are most welcome.
Android Market Link (For android phones)
Below are some code snippets for sending messages to twitter from your application by utilizing a twitter application.
The following code will create a new intent(a request to android for something to happen) for the twidroid application and pass it the message we wish to send. It is important to set the type of the intent as it will fail without it (from at least android 1.5). It will then start the activity and we use a try/catch encase twidroid is not found.
Intent intent = new Intent("com.twidroid.SendTweet");
intent.putExtra("com.twidroid.extra.MESSAGE",
"@stealthcopter Example tweet from android application");
intent.setType("application/twitter");
try {
startActivity(intent);
}
catch (ActivityNotFoundException e) {
/* Handle Exception if Twidroid is not installed */
Toast.makeText(this, "Twidroid not found.", Toast.LENGTH_SHORT).show();
}
But what if someone has a different twitter application installed? this can be solved by offering the user a choice of application to open.
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT,
"@stealthcopter Example tweet from android application");
intent.setType("application/twitter");
try {
startActivity(Intent.createChooser(intent, null));
}
catch (ActivityNotFoundException e) {
/* Handle Exception if no suitable apps installed */
Toast.makeText(this, "No suitable apps found.", Toast.LENGTH_SHORT).show();
}
By combining these two solutions we can make the choice dialog only pop up if the system cannot find the twidroid application. This can be then taken even further by asking the user if they wish to visit the market place to install a twitter application if none is found.
new AlertDialog.Builder(WordCube.this)
.setTitle("Get Twitter")
.setMessage("No twitter Application not found. Goto market and install one now?")
.setIcon(R.drawable.logo)
.setNegativeButton(R.string.dialog_no, null)
.setPositiveButton(R.string.dialog_yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
intentMarket("market://search?q=twitter");
}
})
.show();
Where intentMarket() is defined a to open up the market and search for the specified application passed to it as a string.
public void intentMarket(String url){
Intent i = new Intent(Intent.ACTION_VIEW);
Uri u = Uri.parse(url);
i.setData(u);
try {
startActivity(i);
} catch (ActivityNotFoundException e) {
toastMessage("Market not found.");
}
}
Below shows two screenshots from the wordcube application. This application is avaliable for android, see here for more information and download link (or visit market on your android device).
Update: This is now taken into a complete function in this post.
Settings the text in android is done by finding the object you wish to change, and then using its setText property. Below shows my code updating a textview by its id score_text to say “boring regular text”
((TextView)this.findViewById(R.id.score_text)).setText("boring regular text \n")
This is good but what if you want to include styling in your text, so bold emphasis or italics. Well it’s very simple we first add the android.text.html include:
import android.text.Html;
and then surround our code in Html.fromHtml() this causes them html styling to modify our text.
((TextView)this.findViewById(R.id.score_text)).setText(Html.fromHtml("excitingand cooltext"
Below shows a screenshot of the regular styling and the html styling in an android application.
Android is a brilliant smart phone operating system, this is the start of a short series of guides for starting to program applications for it using the android SDK.
Android SDK
Download the android SDK
Once downloaded untar the SDK
tar xvzf android-sdk_r04-linux_86.tgz
The SDK is not complete as additional files need to be downloaded in order to compile for different versions of android. Open the SDK and AVG management application by moving into the SDK folder and running the following.
sh tools/android
In the avaliable packages select the android versions you wish to develop for, and begin downloading them. Should this fail please read the next section, otherwise skip ahead.
Failing to download
If you cannot download from the google website, goto settings and select “force https://… source to be fetched using http://” and click save and apply.
If this still does not work (as was the case for me) it is possible that for some reason a configuration file was not created for this program, this can be solved by creating it manually:
echo sdkman.force.http=true > ~/.android/androidtool.cfg
Creating Android Virtual Devices
You can create virtual android phones using the SDK and AVD manager, click the Virtual Device tab and select new. Enter a name for the device, and a size for the sd card and simply click create AVD.
Once you’ve created you Virtual Device(s) it should look like the following:
You can test these virtual devices and see how nicely the phones are emulated. This is much more useful once you begin writing applications.
Eclipse
I would highly recommend using eclipse as it, along with the android plugin, greatly simplifies production and testing of applications.
Download eclipse from the ubuntu repositories (or from the eclipse website)
sudo apt-get install eclipse
If you do not already have java installed then you will need to install it.
sudo apt-get install sun-java6-jdk sun-java6-jre
You will need to add the following line to your .bashrc in your home folder so that the android tools can be used in eclipse (and other programs).
export PATH=${PATH}:/home/user/android/sdk/tools
* replace /home/user/android/sdk with the path to where you downloaded the SDK
Installing the android plugin for eclipse
Google’s eclipse plugin install guide.
In eclipse goto help then Install new software and then add the google plugin url
https://dl-ssl.google.com/android/eclipse/
Then install Android DDMS and Android Development Tools.
Should you receive errors (like I did) relating to a missing package you will need to add the eclipse repository and install the missing packages.
http://download.eclipse.org/releases/galileo
You should then have a fully working eclipse with android plugin.
What next?
Now you should have everything setup in order to develop and android applications. I would recommend the google tutorials:
Due to the simple nature of the Caesar cipher, it could easily be brute forced by trying all possible 25 keys and then looking by eye to see if the plaintext was revealed (this too can be automated by checking for common English words to see if the solution was probable). However the much more elegant method of frequency analysis can be used.
Below is a table of the frequency of letters in the English language:
| Letter | Frequency (percent) | Frequency (decimal) | Normalised Frequency |
| a | 8.17% | 0.08167 | 0.64297 |
| b | 1.49% | 0.01492 | 0.11746 |
| c | 2.78% | 0.02782 | 0.21902 |
| d | 4.25% | 0.04253 | 0.33483 |
| e | 12.70% | 0.12702 | 1.00000 |
| f | 2.23% | 0.02228 | 0.17541 |
| g | 2.02% | 0.02015 | 0.15864 |
| h | 6.09% | 0.06094 | 0.47977 |
| i | 6.97% | 0.06966 | 0.54842 |
| j | 0.15% | 0.00153 | 0.01205 |
| k | 0.77% | 0.00772 | 0.06078 |
| l | 4.03% | 0.04025 | 0.31688 |
| m | 2.41% | 0.02406 | 0.18942 |
| n | 6.75% | 0.06749 | 0.53133 |
| o | 7.51% | 0.07507 | 0.59101 |
| p | 1.93% | 0.01929 | 0.15187 |
| q | 0.10% | 0.00095 | 0.00748 |
| r | 5.99% | 0.05987 | 0.47134 |
| s | 6.33% | 0.06327 | 0.49811 |
| t | 9.06% | 0.09056 | 0.71296 |
| u | 2.76% | 0.02758 | 0.21713 |
| v | 0.98% | 0.00978 | 0.07700 |
| w | 2.36% | 0.02360 | 0.18580 |
| x | 0.15% | 0.00150 | 0.01181 |
| y | 1.97% | 0.01974 | 0.15541 |
| z | 0.07% | 0.00074 | 0.00583 |
And shown graphically:
Using the following code we can use frequency analysis to find the solution to ciphertext created using the Caesar shift demonstrated previously (see Caesar shift and Caesar shift using makestrans).
from Numeric import * from string import maketrans def translator(text,alphabet,key): trantab = maketrans(alphabet,key) return text.translate(trantab) def caesar_decode(ciphertext,s): alpha="abcdefghijklmnopqrstuvwxyz" return translator(ciphertext,alpha,alpha[-s:]+alpha[:-s]) class frequency_analysis: def __init__(self, ciphertext): self.cor=[0.64297,0.11746,0.21902,0.33483,1.00000,0.17541, 0.15864,0.47977,0.54842,0.01205,0.06078,0.31688,0.18942, 0.53133,0.59101,0.15187,0.00748,0.47134,0.49811,0.71296, 0.21713,0.07700,0.18580,0.01181,0.15541,0.00583] self.ciphertext=ciphertext.lower() self.freq() self.min_error() self.key=self.minimum[0] self.solution=caesar_decode(self.ciphertext,self.minimum[0]) def freq(self): self.arr=zeros(26,Float64) for l in self.ciphertext: x=ord(l) if (x>=97 and x<=122): self.arr[x-97]+=1.0 self.arr/=max(self.arr) def error(self): e=0 for i in range(0,len(self.arr)): e+=abs(self.arr[i]-self.cor[i])**2 return e def min_error(self): self.minimum=[0,10000] for rot in range(0,25): e=self.error() print rot,e if e<self.minimum[1]: self.minimum[1]=e self.minimum[0]=rot x=self.arr[-1] del self.cor[-1] self.cor.insert(0,x) ciphertext="ymjwj fwj ybt ydujx tk jshwduynts: tsj ymfy bnqq "+\ "uwjajsy dtzw xnxyjw kwtr wjfinsl dtzw infwd fsi tsj ymfy bnqq "+\ "uwjajsy dtzw ltajwsrjsy. ymnx nx f ajwd nrutwyfsy qjxxts yt "+\ "wjrjgjwjxujhnfqqd ktw fyyfhpx zxnsl kwjvzjshd fsfqdxnx bmnhm "+\ "wjvznwj qtsljw ufxxflj tk yjcy ns twijw yt fhmnjaj gjyyjw wjxzqyx." FA=frequency_analysis(ciphertext) print FA.solution
This code will calculate the error in statistical frequency for each letter squared to generate an error for each possible rotation. Using a sufficiently long piece of ciphertext this code should accurately reveal the Caesar rotation use. The table below shows the error for each rotation:
| Rotation | Error |
| 0 | 4.11797847386 |
| 1 | 3.05305477067 |
| 2 | 3.70059678828 |
| 3 | 3.66330931218 |
| 4 | 3.5078619579 |
| 5 | 0.361318100755 |
| 6 | 3.17289666386 |
| 7 | 3.66072641654 |
| 8 | 3.39769855873 |
| 9 | 1.74854802027 |
| 10 | 2.92550921273 |
| 11 | 2.67524757297 |
| 12 | 2.86847189573 |
| 13 | 3.06980318397 |
| 14 | 2.56886153328 |
| 15 | 2.17180117031 |
| 16 | 2.24503724763 |
| 17 | 2.95579718798 |
| 18 | 1.74002183444 |
| 19 | 1.83328601011 |
| 20 | 1.74779021766 |
| 21 | 2.71332097813 |
| 22 | 1.5409364067 |
| 23 | 1.83209213494 |
| 24 | 1.54904808883 |
The lowest error is for 5 rotations (correctly so) with an error of 0.361318100755, the next lowest error is 22 rotations with an error of 1.5409364067. This is ~4.3x difference, which gives a very large degree of confidence to our solution and below is the deciphered text.
there are two types of encryption: one that will prevent your sister from reading your diary and one that will prevent your government. this is a very important lesson to remeberespecially for attacks using frequency analysis which require longer passage of text in order to achieve better results.
Future
The frequency analysis presented here can be used along with some other techniques in order to crack the viginere cipher.












