I want to repeat the Encrypt function along the entire length of the bina / how to do it?
private void carbonFiberButton11_Click_1(object sender, EventArgs e)
{
textBox1.Text = PairConcat(Encrypt(), bina());
}
public static string PairConcat(string Encrypt, string bina)
{
StringBuilder result = new StringBuilder();
int i = 0;
for(; i<Encrypt.Length & i < bina.Length; i++)
{
result.Append(Encrypt[i].ToString());
result.Append(bina[i].ToString());
}
result.Append(Encrypt.Substring(i));
result.Append(bina.Substring(i));
return result.ToString();
}
For example:
string bina = "1234567";
string Encrypt = "abcdefg";
textbox1.text = 1a2b3c4d.. ;but it is doesn't works if I have different length:
string bina = "12345"
string Encrypt = "abc"
textbox1.text = 1a2b3c45 , but I need - 1a2b3c4a5b.
Encrypt function:
string Encrypt() //random to binary
{
var encrypt = textBox4.Text;
StringBuilder binary = new StringBuilder();
for (int i = 0; i < encrypt.Length; i++)
{
binary.Append(Convert.ToString(encrypt[i], 2).PadLeft(8, '0'));
}
return binary.ToString();
}
I can't understand what to do/ Help me, please
Just make the Encrypt string in minimum as long as the bina string.
// Calculate smallest multiple of Encrypt.Length at least as long as bina.Length
int lb = bina.Length;
int le = Encrypt.Length;
int bufferLength = (lb + le - 1) / le * le;
var sb = new StringBuilder(Encrypt, bufferLength);
while (sb.Length < lb) {
sb.Append(Encrypt);
}
Encrypt = sb.ToString();
string result = String.Join("", bina.Zip(Encrypt, (a, b) => a.ToString() + b));
The LINQ Zip method combines 2 sequences by providing pairs of items from the two sequences until one sequence ends. Here the sequences consist of chars.
The StringBuilder works most efficiently if does not have to resize its internal buffer. I calculate it by using integer arithmetic.
Related
I, like many hopeless romantics in the online world, believe that I can successfully mine bit coins. Problems is, I can't get the basic algorithm correct for taking data from a previous mine block and creating the hash for the next mined block. I understand from several articles that we start with the current hash of a block, reverse and append the merkel root, add the nonce, then get the SHA256 hash of that string.
static void Main(string[] args)
{
//get the hash of the current block
string currentHash =
#"000000000000000000c5c04011f9a3fb5f46064fed7e06dcdae69024ed6484c1";
//get the merkel root
string merkel =
#"f73a382814c51cbc5a59ab9817ac54c63decb7b3dac5b049df5213c029162bdf";
//reverese the merkel root
char[] c = merkel.ToCharArray();
Array.Reverse(c);
merkel = new string(c);
//get a hash object that returns SHA256
Hash hash = new Hash();
//get the nonce that mined the block
uint nonce = 3546041956;
//string together current hash, merkel root and the hex of the nonce
string stringTotal = currentHash + merkel + nonce.ToString("x2");
//calculate the SHA256 hash of the
string nextHash = hash.GetHash(stringTotal);
Console.WriteLine(nextHash);
Console.ReadKey();
}
Anyone know the correct algorithm? I used this block https://blockchain.info/block-height/477065 and tried to calculate the hash for the next block.
So I was curious about the same thing. This is what I came up with. It's obviously not production quality, but it gets the idea across and seems to work.
It probably would have been much easier if it weren't for the reverse and swap logic that was practically undocumented everything I was looking.
Anyways, hope this helps. I found a bunch of help here if you're interested: http://trogers.net/2018/01/29/how-to-validate-a-bitcoin-blocks-proof-of-work-c/
class Program
{
static void Main(string[] args)
{
// https://blockchain.info/block-height/286819
int version = 2;
string previousBlock = "000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717";
string merkelRoot = "871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a";
uint nonce = 856192328;
long timestamp = new DateTimeOffset(DateTime.SpecifyKind(DateTime.Parse("2014-02-20 04:57:25"), DateTimeKind.Utc)).ToUnixTimeSeconds();
uint bits = 419520339;
var header = new StringBuilder()
.Append(ReverseAndSwap(version.ToString("D8")))
.Append(ReverseAndSwap(previousBlock))
.Append(ReverseAndSwap(merkelRoot))
.Append(ReverseAndSwap(timestamp.ToString("x2")))
.Append(ReverseAndSwap(bits.ToString("x2")))
.Append(ReverseAndSwap(nonce.ToString("x2")))
.ToString();
Debug.Assert(string.CompareOrdinal(header, "0200000017975b97c18ed1f7e255adf297599b55330edab87803c81701000000000000008a97295a2747b4f1a0b3948df3990344c0e19fa6b2b92b3a19c8e6badc141787358b0553535f011948750833") == 0);
var bytes = HexToBytes(header);
SHA256 sha = new SHA256Managed();
bytes = sha.ComputeHash(sha.ComputeHash(bytes)).Reverse().ToArray();
var hash = BytesToHex(bytes);
Debug.Assert(string.CompareOrdinal(hash, "0000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50") == 0);
}
private static string ReverseAndSwap(string input)
{
StringBuilder sb = new StringBuilder();
for (var i = input.Length - 1; i >= 0; i--)
{
sb.Append(input[i - (i % 2 == 0 ? -1 : 1)]);
}
return sb.ToString();
}
public static byte[] HexToBytes(string hex)
{
byte[] hexAsBytes = new byte[hex.Length / 2];
for (int index = 0; index < hexAsBytes.Length; index++)
{
string byteValue = hex.Substring(index * 2, 2);
hexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return hexAsBytes;
}
public static string BytesToHex(byte[] bytes)
{
var output = new StringBuilder(bytes.Length * 2);
for (int i = 0; i < bytes.Length; ++i)
{
output.AppendFormat("{0:x2}", bytes[i]);
}
return output.ToString();
}
}
I have a problem to display fo result of my looping code, this is my code
private int n = 689;
private int e = 41;
private int d = 137;
public void enkrip()
{
string text = "indra";
byte[] asciiBytes = Encoding.ASCII.GetBytes(text);
for (int i = 0; i < text.Length; i++)
{
int vout = Convert.ToInt32(asciiBytes[i]);
int c = (int)BigInteger.ModPow(vout, e, n);
char cipher = Convert.ToChar(c);
textBox2.Text = char.ToString(cipher);
}
}
but it not appear in textbox, any help?
You are overwriting the text in your box with each loop.
If you want the final string in your text box, your loop should build a string, and then once the loop is done, put the final string into your text box.
On each iteration of the loop you're setting the Text to a single character. Build the string up, and assign it to the text outside the loop
string text = "indra";
byte[] asciiBytes = Encoding.ASCII.GetBytes(text);
char[] result = new char[text.Length];
for (int i = 0; i < text.Length; i++)
{
int vout = Convert.ToInt32(asciiBytes[i]);
int c = (int)BigInteger.ModPow(vout, e, n);
char cipher = Convert.ToChar(c);
result[i] = cipher;
}
textBox2.Text = new string(result);
You're only ever going to see the last value in the text box, since you over-write the text box's .Text property in every iteration of the loop. Even if the UI does update between loop iterations, it would be too fast to perceive.
You could append to the text box in each iteration:
textBox2.Text += char.ToString(cipher);
Or perhaps build a string in the loop and then set the text box afterward (generally the preferred solution):
var sb = new StringBuilder();
for (int i = 0; i < text.Length; i++)
{
//...
sb.Append(char.ToString(cipher));
}
textBox2.Text = sb.ToString();
Probably, you want a combine all the results into a single string:
public void enkrip() {
string text = "indra";
byte[] asciiBytes = Encoding.ASCII.GetBytes(text);
// "iùŢĕ"
textBox2.Text = String.Concat(asciiBytes
.Select(b => (char)BigInteger.ModPow(b, e, n)));
}
please note, that asciiBytes.Length and text.Length are different values (in general case). To represent encrypted text as hex codes:
public void enkrip() {
string text = "indra";
byte[] asciiBytes = Encoding.ASCII.GetBytes(text);
// 0069, 00f9, 0162, 0115, 001c
textBox2.Text = String.Join(", ", asciiBytes
.Select(b => BigInteger.ModPow(b, e, n).ToString("x4")));
}
My final suggestion is to extract a method:
public static String Encrypt(String text) {
if (String.IsNullOrEmpty(text))
return text;
int n = 689;
int e = 41;
return String.Concat(Encoding.ASCII.GetBytes(text)
.Select(b => (char)BigInteger.ModPow(b, e, n)));
}
...
// and so you can encrypt as easy as
textBox2.Text = Encrypt("indra");
I want to convert/find each of my string characters to (int) and reverse this operation.
I manage to do the first part,but the seconds one is giving me some problems.
string input;
string encrypt = ""; string decrypt = "";
input = textBox.Text;
foreach (char c in input)
{
int x = (int)c;
string s = x.ToString();
encrypt += s;
}
MessageBox.Show(encrypt);
foreach (int i in encrypt)
{
char c = (char)i;
string s = c.ToString();
decrypt += c;
}
MessageBox.Show(decrypt);
Thanks!
Here is a fixed program according to my advise above
string encrypt = ""; string decrypt = "";
string input = Console.ReadLine();
var length = input.Length;
int[] converted = new int[length];
for (int index = 0; index < length; index++)
{
int x = input[index];
string s = x.ToString();
encrypt += s;
converted[index] = x;
}
Console.WriteLine(encrypt);
for (int index = 0; index < converted.Length; index++)
{
char c = (char)converted[index];
string s = c.ToString();
decrypt += s;
}
Console.WriteLine(decrypt);
This will not work as is, because you're adding numbers to a string with no padding.
Let's assume the first three letter's values are '1','2','3', you'll have a string with "123".
Now, if you know each letter is 1 int length, you're good, but what happens if 12 is valid? and 23?
This might not be a "real" issues in your case because the values will probably be all 2 ints long, but it's very lacking (unless it's homework, in which case, oh well ...)
The ascii values for the alphabet will go from 65 for A to 122 z.
You can either pad them (say 3 chars per number, so 065 for A, and so on), delimit them (have ".", and split the string on that), use an array (like shahar's suggestion), lists, etc etc ...
In Your scenario, encryption may give output as you expected but its hard to decrypt the encrypted text using such mechanism. so I just do some customization on your code and make it workable here.
i suggest a similar one here:
string input;
string encrypt = ""; string decrypt = "";
int charCount = 0;
input = "textBox.Text";
foreach (char c in input)
{
int x = (int)c;
string s = x.ToString("000");
encrypt += s;
charCount++;
}
// MessageBox.Show(encrypt);
while (encrypt.Length > 0)
{
int item = Int32.Parse(encrypt.Substring(0, 3));
encrypt = encrypt.Substring(3);
char c = (char)item;
string s = c.ToString();
decrypt += c;
}
Reason for your code is not working:
You have declared encrypt as string and iterate through each integer in that string value, it is quiet not possible.
if you make that loop to iterate through each characters in that string value again it gives confusion. as :
lets take S as your input. its equivalent int value is 114 so if you make a looping means it will give 1,1,4, you will not get s back from it.
I'm trying to generate a 16 chars random string with NO DUPLICATE CHARS. I thoght that it shouldn't be to hard but I'm stuck.
I'm using 2 methods, one to generate key and another to remove duplicate chars. In main I've created a while loop to make sure that generated string is 16 chars long.
There is something wrong with my logic because it just shoots up 16-char string
with duplicates. Just can't get it right.
The code:
public string RemoveDuplicates(string s)
{
string newString = string.Empty;
List<char> found = new List<char>();
foreach (char c in s)
{
if (found.Contains(c))
continue;
newString += c.ToString();
found.Add(c);
}
return newString;
}
public static string GetUniqueKey(int maxSize)
{
char[] chars = new char[62];
chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
byte[] data = new byte[1];
RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
crypto.GetNonZeroBytes(data);
data = new byte[maxSize];
crypto.GetNonZeroBytes(data);
StringBuilder result = new StringBuilder(maxSize);
foreach (byte b in data)
{
result.Append(chars[b % (chars.Length)]);
}
return result.ToString();
}
string builder = "";
do
{
builder = GetUniqueKey(16);
RemoveDuplicates(builder);
lblDir.Text = builder;
Application.DoEvents();
} while (builder.Length != 16);
Consider implementing shuffle algorithm with which you will shuffle your string with unique characters and then just pick up first 16 characters.
You can do this in-place, by allocating single StringBuffer which will contain your initial data ("abc....") and just use Durstenfeld's version of the algorithm to mutate your buffer, than return first 16 chars.
There are many algorithms for this.
One easy one is:
Fill an array of chars with the available chars.
Shuffle the array.
Take the first N items (where N is the number of characters you need).
Sample code:
using System;
namespace ConsoleApplication2
{
internal class Program
{
private static void Main(string[] args)
{
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
Random rng = new Random();
for (int i = 0; i < 10; ++i)
{
string randomString = RandomString(16, chars, rng);
Console.WriteLine(randomString);
}
}
public static string RandomString(int n, char[] chars, Random rng)
{
Shuffle(chars, rng);
return new string(chars, 0, n);
}
public static void Shuffle(char[] array, Random rng)
{
for (int n = array.Length; n > 1; )
{
int k = rng.Next(n);
--n;
char temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
}
}
const string chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
var r = new Random();
var s = new string(chars.OrderBy(x => r.Next()).Take(16).ToArray());
I am using a GUID generation method it itself generates random strings and you can modify it if a number appears in the beginning,
use the code given below:
string guid = System.Guid.NewGuid().ToString("N");
while (char.IsDigit(guid[0]))
guid = System.Guid.NewGuid().ToString("N");
Hope that helps.
See if this helps:
RandomString()
{
string randomStr = Guid.NewGuid().ToString();
randomStr = randomStr.Replace("-", "").Substring(0, 16);
Console.WriteLine(randomStr);
}
This returns alpha-numeric string.
at a recent interview I attended, the programming question that was asked was this. Write a function that will take as input two strings. The output should be the result of concatenation.
Conditions: Should not use StringBuffer.Append or StringBuilder.Append or string objects for concatenation;that is, they want me to implement the pseudo code implementation of How StringBuilder or StringBuffer's Append function works.
This is what I did:
static char[] AppendStrings(string input, string append)
{
char[] inputCharArray = input.ToCharArray();
char[] appendCharArray = append.ToCharArray();
char[] outputCharArray = new char[inputCharArray.Length + appendCharArray.Length];
for (int i = 0; i < inputCharArray.Length; i++)
{
outputCharArray[i] = inputCharArray[i];
}
for (int i = 0; i < appendCharArray.Length; i++)
{
outputCharArray[input.Length + i] = appendCharArray[i];
}
return outputCharArray;
}
While this is a working solution, is there a better way of doing things?
is LINQ legal? strings are just can be treated as an enumeration of chars, so they can be used with LINQ (even though there is some cost involved, see comments):
string a = "foo";
string b = "bar";
string c = new string(a.AsEnumerable().Concat(b).ToArray());
or with your method signature:
static char[] AppendStrings(string input, string append)
{
return input.AsEnumerable().Concat(append).ToArray();
}
You can call CopyTo:
char[] output = new char[a.Length + b.Length];
a.CopyTo(0, output, 0, a.Length);
b.CopyTo(0, output, a.Length, b.Length);
return new String(output);
If they don't like that, call .ToCharArray().CopyTo(...).
You can also cheat:
return String.Join("", new [] { a, b });
return String.Format("{0}{1}", a, b);
var writer = new StringWriter();
writer.Write(a);
writer.Write(b);
return writer.ToString();
I would've done something like the following (argument checking omitted for brevity)
public static string Append(string left, string right) {
var array = new char[left.Length + right.Length];
for (var i = 0; i < left.Length; i++) {
array[i] = left[i];
}
for (var i = 0; i < right.Length; i++) {
array[i + left.Length] = right[i];
}
return new string(array);
}
In Java you can just use concat which does not use StringBuilder or StringBuffer.
String a = "foo";
String b = "bar";
String ab = a.concat(b);
The source for String.concat(String) from Oracle's JDK.
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
java default support "+" for append string
String temp="some text";
for(int i=0;i<10;i++)
{
temp=temp+i;
}
Or
temp=temp+" some other text"