How to find SHA1 hash? - sha

i got interesting task at school. I have to find message which sha-1 hash lasts with my birthday example. if i was born on 4th may 1932 then the hash must end with 040532. Any suggestions how to find it out?

my solution in C#:
//A create Sha1 function:
using System.Security.Cryptography;
public static string GetSHA1Hash(string text)
{
var SHA1 = new SHA1CryptoServiceProvider();
byte[] arrayData;
byte[] arrayResult;
string result = null;
string temp = null;
arrayData = Encoding.ASCII.GetBytes(text);
arrayResult = SHA1.ComputeHash(arrayData);
for (int i = 0; i < arrayResult.Length; i++)
{
temp = Convert.ToString(arrayResult[i], 16);
if (temp.Length == 1)
temp = "0" + temp;
result += temp;
}
return result;
}
Source
Then a Random String generator:
private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden
private string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
return builder.ToString();
}
Source
and now you can bruteforce for your combination:
string search = "32";
string result = String.Empty;
int slen = 5;
string myTry = RandomString(slen);
while (!result.EndsWith(search))
{
myTry = RandomString(slen);
result = GetSHA1Hash(myTry);
}
MessageBox.Show(result + " " + myTry);
This would search for a Hash String ending with 32. Happy Bruteforcing :)
EDIT: found one for your example: HXMQVNMRFT gives e5c9fa9f6acff07b89c617c7fd16a9a043040532

Start generating hashes from distinct messages1.
Eventually a hash will be generated with such a property. This is not that bad to brute-force as the range is only 224 (or ~16 million) and SHA is very fast.
There is no shortcut as SHA is a one way cryptographic hash function. In particular here, SHA has the property that "it is infeasible to generate a message that has a given hash".
1 The inputs should be distinct, and a simple counter will suffice. However, it may be more interesting to generate quasi-random messages based on the birthday being sought - e.g. including the date in various forms and sentences Mad Lib style. As long as this doesn't limit the domain, such that there is no qualifying hash, it'll work just as well as any other set of source messages.

Related

String/Array in Java

Does this work? I'm trying to print a message in this.
char[] tempMessage = message.toCharArray();
String[] message2 = message.split(" ");
Integer.toString(number).toCharArray();
for(int x = 0; x<newMessage.length; x++)
{
}
Although its better to use a StringBuilder, I can show it using String(s).
String[] strArr = "hello world".split("\\s+");
String s = String.valueOf(strArr[0].charAt(0))+strArr[0].length()+String.valueOf(strArr[1].charAt(0))+strArr[1].length();
Output : h5w5
String[] message2 = message.split("\\s+");
String output = "";
for(int i = 0; i < message2.length; i++)
{
output += "" + message2[i].charAt(0) + message2[i].length();
}
//output has output string.
TheLostMind's solution is already good, but I think it needs a solution for Strings of arbitrary length.
String outputString = "";
for(String x : message.split("\\s+"))
{
outputString = outputString.concat(x.charAt(0) + x.length());
}
As stated in the comments, this solution is very similiar to brso05's solution. The difference is in using the :-Operator in the for-loop. It's shorter and IMHO easier to understand, as it says 'for each String in the resulting array'.
Also, using the concat()-function is considered safer in my work environment.

Find the prefix which is also a suffix

I'm looking for an optimal solution for this problem.
Given a string s of length n, find a prefix left-to-right equivalent to a suffix right-to-left.
The prefix and suffix can overlap.
Example: given abababa, prefix is [ababa]ba, suffix is ab[ababa].
I am able to go till this
for each i = 0 to n-1, take the prefix ending at i and find if we have an appropriate suffix. It's time is O(n^2) time and O(1) space.
I came up with an optimization where we index the positions of all the characters. This way, we can eliminate set of sample spaces from 1/. Again, the worst case complexity is O(n^2) with O(n) additional space.
Are there any better algorithm for this ?
Make use of the KMP algorithm. The state of the algorithm determines "the longest suffix of the haystack that's still a prefix of the needle". So just take your string as needle and the string without the first character as haystack. Runs in O(N) time and O(N) space.
An implementation with some examples :
public static int[] create(String needle) {
int[] backFunc = new int[needle.length() + 1];
backFunc[0] = backFunc[1] = 0;
for (int i = 1; i < needle.length(); ++i) {
int testing = i - 1;
while (backFunc[testing] != testing) {
if (needle.charAt(backFunc[testing]) == needle.charAt(i-1)) {
backFunc[i] = backFunc[testing] + 1;
break;
} else {
testing = backFunc[testing];
}
}
}
return backFunc;
}
public static int find(String needle, String haystack) {
// some unused character to ensure that we always return back and never reach the end of the
// needle
needle = needle + "$";
int[] backFunc = create(needle);
System.out.println(Arrays.toString(backFunc));
int curpos = 0;
for (int i = 0; i < haystack.length(); ++i) {
while (curpos != backFunc[curpos]) {
if (haystack.charAt(i) == needle.charAt(curpos)) {
++curpos;
break;
} else {
curpos = backFunc[curpos];
}
}
if (curpos == 0 && needle.charAt(0) == haystack.charAt(i)) {
++curpos;
}
System.out.println(curpos);
}
return curpos;
}
public static void main(String[] args) {
String[] tests = {"abababa", "tsttst", "acblahac", "aaaaa"};
for (String test : tests) {
System.out.println("Length is : " + find(test, test.substring(1)));
}
}
Simple implementation in C#:
string S = "azffffaz";
char[] characters = S.ToCharArray();
int[] cumulativeCharMatches = new int[characters.Length];
cumulativeCharMatches[0] = 0;
int prefixIndex = 0;
int matchCount = 0;
// Use KMP type algorithm to determine matches.
// Search for the 1st character of the prefix occurring in a suffix.
// If found, assign count of '1' to the equivalent index in a 2nd array.
// Then, search for the 2nd prefix character.
// If found, assign a count of '2' to the next index in the 2nd array, and so on.
// The highest value in the 2nd array is the length of the largest suffix that's also a prefix.
for (int i = 1; i < characters.Length; i++)
{
if (characters[i] == characters[prefixIndex])
{
matchCount += 1;
prefixIndex += 1;
}
else
{
matchCount = 0;
prefixIndex = 0;
}
cumulativeCharMatches[i] = matchCount;
}
return cumulativeCharMatches.Max();
See:
http://algorithmsforcontests.blogspot.com/2012/08/borders-of-string.html
for an O(n) solution
The code actually calculates the index of the last character in the prefix. For the actual prefix/suffix, you will need to extract the substring from 0 to j (both included, length is j+1)

Count the number of frequency for different characters in a string

i am currently tried to create a small program were the user enter a string in a text area, clicks on a button and the program counts the frequency of different characters in the string and shows the result on another text area.
E.g. Step 1:- User enter:- aaabbbbbbcccdd
Step 2:- User click the button
Step 3:- a 3
b 6
c 3
d 1
This is what I've done so far....
public partial class Form1 : Form
{
Dictionary<string, int> dic = new Dictionary<string, int>();
string s = "";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
s = textBox1.Text;
int count = 0;
for (int i = 0; i < s.Length; i++ )
{
textBox2.Text = Convert.ToString(s[i]);
if (dic.Equals(s[i]))
{
count++;
}
else
{
dic.Add(Convert.ToString(s[i]), count++);
}
}
}
}
}
Any ideas or help how can I countinue because till now the program is giving a run time error when there are same charachter!!
Thank You
var lettersAndCounts = s.GroupBy(c=>c).Select(group => new {
Letter= group.Key,
Count = group.Count()
});
Instead of dic.Equals use dic.ContainsKey. However, i would use this little linq query:
Dictionary<string, int> dict = textBox1.Text
.GroupBy(c => c)
.ToDictionary(g => g.Key.ToString(), g => g.Count());
You are attempting to compare the entire dictionary to a string, that doesn't tell you if there is a key in the dictionary that corresponds to the string. As the dictionary never is equal to the string, your code will always think that it should add a new item even if one already exists, and that is the cause of the runtime error.
Use the ContainsKey method to check if the string exists as a key in the dictionary.
Instead of using a variable count, you would want to increase the numbers in the dictionary, and initialise new items with a count of one:
string key = s[i].ToString();
textBox2.Text = key;
if (dic.ContainsKey(key)) {
dic[key]++;
} else {
dic.Add(key, 1);
}
I'm going to suggest a different and somewhat simpler approach for doing this. Assuming you are using English strings, you can create an array with capacity = 26. Then depending on the character you encounter you would increment the appropriate index in the array. For example, if the character is 'a' increment count at index 0, if the character is 'b' increment the count at index 1, etc...
Your implementation will look something like this:
int count[] = new int [26] {0};
for(int i = 0; i < s.length; i++)
{
count[Char.ToLower(s[i]) - int('a')]++;
}
When this finishes you will have the number of 'a's in count[0] and the number of 'z's in count[25].

Sorting a string using another sorting order string [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I saw this in an interview question ,
Given a sorting order string, you are asked to sort the input string based on the given sorting order string.
for example if the sorting order string is dfbcae
and the Input string is abcdeeabc
the output should be dbbccaaee.
any ideas on how to do this , in an efficient way ?
The Counting Sort option is pretty cool, and fast when the string to be sorted is long compared to the sort order string.
create an array where each index corresponds to a letter in the alphabet, this is the count array
for each letter in the sort target, increment the index in the count array which corresponds to that letter
for each letter in the sort order string
add that letter to the end of the output string a number of times equal to it's count in the count array
Algorithmic complexity is O(n) where n is the length of the string to be sorted. As the Wikipedia article explains we're able to beat the lower bound on standard comparison based sorting because this isn't a comparison based sort.
Here's some pseudocode.
char[26] countArray;
foreach(char c in sortTarget)
{
countArray[c - 'a']++;
}
int head = 0;
foreach(char c in sortOrder)
{
while(countArray[c - 'a'] > 0)
{
sortTarget[head] = c;
head++;
countArray[c - 'a']--;
}
}
Note: this implementation requires that both strings contain only lowercase characters.
Here's a nice easy to understand algorithm that has decent algorithmic complexity.
For each character in the sort order string
scan string to be sorted, starting at first non-ordered character (you can keep track of this character with an index or pointer)
when you find an occurrence of the specified character, swap it with the first non-ordered character
increment the index for the first non-ordered character
This is O(n*m), where n is the length of the string to be sorted and m is the length of the sort order string. We're able to beat the lower bound on comparison based sorting because this algorithm doesn't really use comparisons. Like Counting Sort it relies on the fact that you have a predefined finite external ordering set.
Here's some psuedocode:
int head = 0;
foreach(char c in sortOrder)
{
for(int i = head; i < sortTarget.length; i++)
{
if(sortTarget[i] == c)
{
// swap i with head
char temp = sortTarget[head];
sortTarget[head] = sortTarget[i];
sortTarget[i] = temp;
head++;
}
}
}
In Python, you can just create an index and use that in a comparison expression:
order = 'dfbcae'
input = 'abcdeeabc'
index = dict([ (y,x) for (x,y) in enumerate(order) ])
output = sorted(input, cmp=lambda x,y: index[x] - index[y])
print 'input=',''.join(input)
print 'output=',''.join(output)
gives this output:
input= abcdeeabc
output= dbbccaaee
Use binary search to find all the "split points" between different letters, then use the length of each segment directly. This will be asymptotically faster then naive counting sort, but will be harder to implement:
Use an array of size 26*2 to store the begin and end of each letter;
Inspect the middle element, see if it is different from the element left to it. If so, then this is the begin for the middle element and end for the element before it;
Throw away the segment with identical begin and end (if there are any), recursively apply this algorithm.
Since there are at most 25 "split"s, you won't have to do the search for more than 25 segemnts, and for each segment it is O(logn). Since this is constant * O(logn), the algorithm is O(nlogn).
And of course, just use counting sort will be easier to implement:
Use an array of size 26 to record the number of different letters;
Scan the input string;
Output the string in the given sorting order.
This is O(n), n being the length of the string.
Interview questions are generally about thought process and don't usually care too much about language features, but I couldn't resist posting a VB.Net 4.0 version anyway.
"Efficient" can mean two different things. The first is "what's the fastest way to make a computer execute a task" and the second is "what's the fastest that we can get a task done". They might sound the same but the first can mean micro-optimizations like int vs short, running timers to compare execution times and spending a week tweaking every millisecond out of an algorithm. The second definition is about how much human time would it take to create the code that does the task (hopefully in a reasonable amount of time). If code A runs 20 times faster than code B but code B took 1/20th of the time to write, depending on the granularity of the timer (1ms vs 20ms, 1 week vs 20 weeks), each version could be considered "efficient".
Dim input = "abcdeeabc"
Dim sort = "dfbcae"
Dim SortChars = sort.ToList()
Dim output = New String((From c In input.ToList() Select c Order By SortChars.IndexOf(c)).ToArray())
Trace.WriteLine(output)
Here is my solution to the question
import java.util.*;
import java.io.*;
class SortString
{
public static void main(String arg[])throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
// System.out.println("Enter 1st String :");
// System.out.println("Enter 1st String :");
// String s1=br.readLine();
// System.out.println("Enter 2nd String :");
// String s2=br.readLine();
String s1="tracctor";
String s2="car";
String com="";
String uncom="";
for(int i=0;i<s2.length();i++)
{
if(s1.contains(""+s2.charAt(i)))
{
com=com+s2.charAt(i);
}
}
System.out.println("Com :"+com);
for(int i=0;i<s1.length();i++)
if(!com.contains(""+s1.charAt(i)))
uncom=uncom+s1.charAt(i);
System.out.println("Uncom "+uncom);
System.out.println("Combined "+(com+uncom));
HashMap<String,Integer> h1=new HashMap<String,Integer>();
for(int i=0;i<s1.length();i++)
{
String m=""+s1.charAt(i);
if(h1.containsKey(m))
{
int val=(int)h1.get(m);
val=val+1;
h1.put(m,val);
}
else
{
h1.put(m,new Integer(1));
}
}
StringBuilder x=new StringBuilder();
for(int i=0;i<com.length();i++)
{
if(h1.containsKey(""+com.charAt(i)))
{
int count=(int)h1.get(""+com.charAt(i));
while(count!=0)
{x.append(""+com.charAt(i));count--;}
}
}
x.append(uncom);
System.out.println("Sort "+x);
}
}
Here is my version which is O(n) in time. Instead of unordered_map, I could have just used a char array of constant size. i.,e. char char_count[256] (and done ++char_count[ch - 'a'] ) assuming the input strings has all ASCII small characters.
string SortOrder(const string& input, const string& sort_order) {
unordered_map<char, int> char_count;
for (auto ch : input) {
++char_count[ch];
}
string res = "";
for (auto ch : sort_order) {
unordered_map<char, int>::iterator it = char_count.find(ch);
if (it != char_count.end()) {
string s(it->second, it->first);
res += s;
}
}
return res;
}
private static String sort(String target, String reference) {
final Map<Character, Integer> referencesMap = new HashMap<Character, Integer>();
for (int i = 0; i < reference.length(); i++) {
char key = reference.charAt(i);
if (!referencesMap.containsKey(key)) {
referencesMap.put(key, i);
}
}
List<Character> chars = new ArrayList<Character>(target.length());
for (int i = 0; i < target.length(); i++) {
chars.add(target.charAt(i));
}
Collections.sort(chars, new Comparator<Character>() {
#Override
public int compare(Character o1, Character o2) {
return referencesMap.get(o1).compareTo(referencesMap.get(o2));
}
});
StringBuilder sb = new StringBuilder();
for (Character c : chars) {
sb.append(c);
}
return sb.toString();
}
In C# I would just use the IComparer Interface and leave it to Array.Sort
void Main()
{
// we defin the IComparer class to define Sort Order
var sortOrder = new SortOrder("dfbcae");
var testOrder = "abcdeeabc".ToCharArray();
// sort the array using Array.Sort
Array.Sort(testOrder, sortOrder);
Console.WriteLine(testOrder.ToString());
}
public class SortOrder : IComparer
{
string sortOrder;
public SortOrder(string sortOrder)
{
this.sortOrder = sortOrder;
}
public int Compare(object obj1, object obj2)
{
var obj1Index = sortOrder.IndexOf((char)obj1);
var obj2Index = sortOrder.IndexOf((char)obj2);
if(obj1Index == -1 || obj2Index == -1)
{
throw new Exception("character not found");
}
if(obj1Index > obj2Index)
{
return 1;
}
else if (obj1Index == obj2Index)
{
return 0;
}
else
{
return -1;
}
}
}

Generate string of random characters cocoa?

I know how to generate random numbers, but what I really need is a string of random characters. This is what I have so far:
NSString *letters = #"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789?%$";
char generated;
generated = //how do i define this?
NSLog(#"generated =%c", generated);
[textField setStringValue:generated];
-(NSString*)generateRandomString:(int)num {
NSMutableString* string = [NSMutableString stringWithCapacity:num];
for (int i = 0; i < num; i++) {
[string appendFormat:#"%C", (unichar)('a' + arc4random_uniform(25))];
}
return string;
}
then Call it like this for a 5 letter string:
NSString* string = [self generateRandomString:5];
See this SO Q & A.
Generate a random alphanumeric string in Cocoa

Resources