Converting C++ Function to C# (String problems) - c#

I'm trying to convert a code from C++ to C#, but I'm not being able to do it...
std::string Cipher(std::string Str)
{
char Key[5] = { 'H', 'S', 'M', 'K', 'V' };
std::string Encrypted = Str;
for (unsigned int i = 0; i < Str.size(); i++)
{
Encrypted[i] = Str[i] ^ Key[i % (sizeof(Key) / sizeof(char))];
}
return Encrypted;
}
What I got so far in C# is this:
public string Cipher(string Str)
{
char[] Key = new char[5] { 'H', 'S', 'M', 'K', 'V' };
string Encrypted = Str;
for(int i = 0; i < Str.Length; i++)
{
Encrypted[i] = Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]; //line 29
}
return Encrypted;
}
But I keep getting this error:
Property or indexer 'string.this[int]' cannot be assigned to -- it is read only (on line 29)
I found out that it has something to do with immutability of strings, so I tried this:
public string Cipher(string Str)
{
char[] Key = new char[5] { 'H', 'S', 'M', 'K', 'V' };
string Encrypted = Str;
StringBuilder sb = new StringBuilder(Encrypted);
for (int i = 0; i < Str.Length; i++)
{
sb[i] = Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]; //line 30
}
return Encrypted;
}
But, now I get this error:
Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?) (on line 30)
Anyone can help?
Thanks

Close! You are right to use StringBuilder. However, ^ -operator (bitwise XOR) makes C# intepret the result as int. Since you know it's still a char, just add cast:
for (int i = 0; i < Str.Length; i++)
{
sb[i] = (char)(Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]); //line 30
}
Othewise I'm not sure if this does exactly the same as C++ implementation. (sizeof(Key) / sizeof(char) is basically the length of the array. So you should just use Key.length at C# implementation. So a bit more accurate one would be
for (int i = 0; i < Str.Length; i++)
{
sb[i] = (char)(Str[i] ^ Key[i % Key.Length]); //line 30
}

Replace
Encrypted[i] = Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]; //line 29
with
Encrypted[i] = Str[i] ^ Key[i % Key.Lenght]; //line 29
And you can replace characters in a string with:
"1234567890123".Remove(9,1).Insert(9,"A")
Using a string builder is a smarter choice though.

Related

Counter goes down by 4 at the time instead of one (C#)

I am new at C# and after learning the basics I've decided that I wanna make a Hangman game. The problem is that a counter that normally counts down from 8 by 1 each time I miss a letter is counting down by 4 and I have no idea why.
static void Main(string[] args)
{
int Chances= 8;
bool key = false;
int N= 10;
char[] Word = { 'P', 'R', 'O', 'G', 'R', 'A', 'M' };
Console.WriteLine("The word is:_ _ _ _ _ _ _");
Console.Write("Please input a letter:");
while (key == false)
{
char letter = Convert.ToChar(Console.Read());
N = Numberofletter(letter);
Console.WriteLine(N);
while (N == 0 && Chances > 0)
{
Chances--;
Console.WriteLine("The letter is incorrect you have " + K + " tries Remaining");
letter = Convert.ToChar(Console.Read());
};
if (Chances == 0)
{
Console.WriteLine("Gameover");
return;
}
static int Numberofletter(char letter)
{
int N = 0;
char[] Word = { 'P', 'R', 'O', 'G', 'R', 'A', 'M' };
if (Word[0] == letter)
{ N = 1; }
else if (Word[1] == letter)
{ N = 2; }
else if (Word[2] == letter)
{ N = 3; }
else if (Word[3] == letter)
{ N = 4; }
else if (Word[5] == letter)
{ N = 6; }
else if (Word[6] == letter)
{ N = 7; }
else { N = 0; }
return N;
}
The problem is in your while loop.
You enter the loop with N = position of the guessed letter = 0.
INSIDE the loop, you ask for another letter, but NEVER calculate its position.
So even if the letter is in the word, you've never re-assigned the value of N. This means the loop will keep running and decrementing chances until chances < 0;
Simply add
N = Numberofletter(letter);
after you read in the next letter.
I don't know if anyone else will have the same problem as me but I will post my mistake here so at least I hope it will not be repeated
instead of letter=Convert.ToChar(Console.Read());
you should use letter=Convert.ToChar(Console.ReadLine());
i don't know why was that the problem but it happend try it out randomly and it worked

rewrite c# Stopwatch to c++

I'm rewriting this stopwatch code from C# to C++.
I have rewritten some of the code (I can attach it if you think it's helpful) but confused about the lines after var watch = Stopwatch.StartNew(). Does C++ have similar things like this? What kind of variable type should I put for watch in C++?
namespace BruteForcePasswordGeneration
{
class Program
{
static void Main(string[] args)
{
char[] chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
int passwordLength=0;
Console.WriteLine("Enter the password length");
passwordLength = Convert.ToInt32(Console.ReadLine());
BigInteger iPossibilities = (BigInteger)Math.Pow((double)chars.Length, (double)passwordLength);
Console.WriteLine("{0} words total. Press enter to continue;", iPossibilities);
Console.ReadLine();
var watch = Stopwatch.StartNew();
for (BigInteger i = 0; i < iPossibilities; i++)
{
string theword = "";
BigInteger val = i;
for (int j = 0; j < passwordLength; j++)
{
BigInteger ch = val % chars.Length;
theword = chars[(int)ch] + theword;
val = val / chars.Length;
}
Console.WriteLine(theword);
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("It took {0} seconds to generate {1} possible combinations", elapsedMs / 1000, iPossibilities);
Console.ReadLine();
}
}
}
Although you can write a "stopwatch" class in C++ if you want, the usual is to just use high_resolution_clock::now() to get the start and stop times. You then use duration_cast to get the difference in the form you want.
If you'll forgive me, I don't see any real point in requiring the user to enter the password length after starting the program. At least to me, it seems easier to use something like "gen_passwords 4" to generate all the passwords of length 4.
That gives code something on this general order:
#include <iostream>
#include <chrono>
#include <string>
int main(int argc, char **argv) {
static const std::string chars{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
if (argc != 2) {
std::cerr << "Usage: generate <password length>\n";
return EXIT_FAILURE;
}
int passwordLength = std::stoi(argv[1]);
unsigned long long iPossibilities = std::pow(chars.size(), passwordLength);
using namespace std::chrono;
auto start = high_resolution_clock::now();
for (unsigned long long i = 0; i < iPossibilities; i++) {
std::string theword;
unsigned long long val = i;
for (int j = 0; j < passwordLength; j++) {
size_t ch = val % chars.size();
theword = chars[ch] + theword;
val /= chars.size();
}
std::cout << theword << '\n';
}
auto stop = high_resolution_clock::now();
double elapsed = duration_cast<milliseconds>(stop - start).count() / 1000.0;
std::cerr << "It took " << elapsed << " seconds to generate " << iPossibilities << " combinations\n";
}

Checking to see the char equivalent of my int value

Okay i might not have explained it to the best of my ability but i'm a beginner and i would like to make a piece of code that does this :
you have a string and you need to find each vowel in it and multiply each vowel's position in the string by its position in the alphabet and add all the sums together
example : steve: has 2 vowels the first e's position is 3 and its position in the alphabet is 5. and the second's position in the alphabet and the string is 5
so the sum is 5*3 + 5*5 = 40
this is what i did . idk what to do now or how to approach it
var vowels = new char[] {'a', 'e', 'i', 'o', 'u', 'y', 'A','E','I', 'O', 'U','Y'};
var chars = new List<char>();
List<int> indexes = new List<int>();
Console.WriteLine("Write something : ");
var input = Console.ReadLine();
int index;
foreach (var vowel in vowels)
{
if (input.Contains(vowel))
{
index = input.IndexOf(vowel);
indexes.Add(index + 1);
chars.Add(vowel);
}
}
Consider this approach:
using System;
using System.Linq;
using System.Collections.Generic;
namespace Whatever
{
class Program
{
static void Main(string[] args)
{
var vowels = new Dictionary<string, int>(5, StringComparer.OrdinalIgnoreCase) { { "a", 1 }, { "e", 5 }, { "i", 9 }, { "o", 15 }, { "u", 21 } };
Console.WriteLine("Write something : ");
var input = Console.ReadLine();
var sum = input.Select((value, index) => new { value, index })
.Sum(x =>
{
vowels.TryGetValue(x.value.ToString(), out var multiplier);
return (x.index + 1) * multiplier;
});
Console.ReadLine();
}
}
}
The Select projects the original string as an anonymous type with the char and its index included.
The Sum checks if the string is a vowel - and if it is it multiplies the position (index + 1) by the position in the alphabet (from vowels).
vowels is case insensitive so that "A" and "a" are treated the same.
If the compiler complains about the out var then use:
int multiplier = 0;
vowels.TryGetValue(x.value.ToString(), out multiplier);
return (x.index + 1) * multiplier;
instead.
i figured it out right here
for (int i = 0; i < indexes.Count; i++)
{
sumofone += indexes[i] * (char.ToUpper(chars[i]) - 64);
}
You can do this (Reference is from here):
var vowels = new char[] { 'a', 'e', 'i', 'o', 'u' };
Console.WriteLine("Write something : ");
var input = Console.ReadLine().ToLower();
int total = 0;
for (int temp = 1; temp <= input.Length; temp++)
{
if (vowels.Contains(input[temp - 1]))
{
total += temp * (char.ToUpper(input[temp -1]) - 64);
}
}
Console.WriteLine("The length is " + total);

How to print a diamond shape composed of letters? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I want to learn how can I print diamond as follows: I am beginner, so many many thanks for Help
Given a letter print a diamond starting with 'A'
with the supplied letter at the widest point.
For example: print-diamond 'E' prints
A
B B
C C
D D
E E
D D
C C
B B
A
For example: print-diamond 'C' prints
A
B B
C C
B B
A
Actually, your code has two errors (I'm not considering efficiency of your code and algorhims).
First: when you are constructing diamond, for-loop should be not for (int i = 0; i < letter_number + i; i++) but for (int i = 0; i <= letter_number; i++).
Second: when you are drawing diamond - variable j should be placed out of loop, and you should use WriteLine instead of Write.
For example, drawing part of your code can be something like this:
Console.WriteLine();
int jj = 1;
for (int i = 0; i < 2 * letter_number + 1; i++)
{
if (i < letter_number + 1)
Console.WriteLine(diamond[i]);
else
{
Console.WriteLine(diamond[i - 2 * jj]);
jj++;
}
}
Side note: int letter_number; should be initialized as int letter_number = 0; or something like this, because you are assigning it's value under condition and not in every case later in the code, and actually code you've provided even don't compile without this explicit initialization.
Try this. Tested working.
using System;
namespace ConsoleApplication
{
internal class Program
{
private static void Main(string[] args)
{
char[] letter = new char[26]
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z'
};
int letter_number = 0;
//array of strings
string[] diamond = new string[52];
//get the letter
Console.WriteLine("User enters a Letter between A and Z ");
char user_letter = Console.ReadKey().KeyChar;
Console.WriteLine("");
//search for letter number in the array letter
for (int i = 0; i < letter.Length; i++)
{
if (letter[i] == user_letter)
{
letter_number = i;
break;
}
}
//construct diamond
for (int i = 0; i <= letter_number; i++)
{
//add initial spaces
for (int j = 0; j < letter_number - i; j++)
{
diamond[i] += " ";
}
//add letter (first time)
diamond[i] += letter[i];
//add space between letters
if (letter[i] != 'A')
{
for (int j = 0; j < 2*i - 1; j++)
{
diamond[i] += " ";
}
//add letter (second time)
diamond[i] += letter[i];
}
// Draw the first part of the diamond as it's composing.
Console.WriteLine(diamond[i]);
}
for (int i = letter_number - 1; i >= 0; i--)
{
// Draw the second part of the diamond
// Writing the diamondArray in reverse order.
Console.WriteLine(diamond[i]);
}
// Mark a pause
Console.ReadKey();
}
}
}
Output :
User enters a Letter between A and Z
K
A
B B
C C
D D
E E
F F
G G
H H
I I
J J
K K
J J
I I
H H
G G
F F
E E
D D
C C
B B
A

Convert double into hex in C#

I have this value:
double headingAngle = 135.34375;
I would like to convert it to HEX and print the HEX to the console. I have already converted a string and int into their respective HEX values, but a double seems to be much more tricky. Can someone point me in the right direction?
Well, I googled for a minute or two and according to this
here is a quite ellegant solution
double d = 12.09;
Console.WriteLine("Double value: " + d.ToString());
byte[] bytes = BitConverter.GetBytes(d);
Console.WriteLine("Byte array value:");
Console.WriteLine(BitConverter.ToString(bytes));
You can convert base 10 to base 16 by continually multiplying the fraction by 16, stripping out the 'whole' number, and repeating with the remainder.
So to convert 0.1 Decimal to Hex
0.1 * 16
= 1.6
So 1 becomes the first hex value. Keep going with the remaining 0.6
0.6 * 16 = 9.6
So 9 becomes the second hex value. Keeping going with the remaining 0.6
0.6 * 16 = 9.6
etc.
So 0.1 Decimal = 0.19999.. recurring hex
From memory this works for any radix. Obviously in hex a whole value of 10 would be A etc.
Assuming you want to convert to hexadecimal base/radix, the following should do the trick:
static void Main(string[] args)
{
Console.WriteLine(Base16(135.34375, 10));
Console.ReadLine();
}
private static string Base16(double number, int fractionalDigits)
{
return Base(number, fractionalDigits, new char[]{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' });
}
private static string Base(double number, int fractionalDigits, params char[] characters)
{
int radix = characters.Length;
StringBuilder sb = new StringBuilder();
// The 'whole' part of the number.
long whole = (long)Math.Floor(number);
while (whole > 1)
{
sb.Insert(0, characters[whole % radix]);
whole = whole / radix;
}
// The fractional part of the number.
double remainder = number % 1;
if (remainder > Double.Epsilon || remainder < -Double.Epsilon)
{
sb.Append('.');
double nv;
for (int i = 0; i < fractionalDigits; i++)
{
nv = remainder * radix;
if (remainder < Double.Epsilon && remainder > -Double.Epsilon)
break;
sb.Append(characters[(int)Math.Floor(nv)]);
remainder = nv % 1;
}
}
return sb.ToString();
}
The hexadecimal conversion of 135.34375 is 87.58.
BitConverter.DoubleToInt64Bits(value).ToString("X")
Try this:
public static string Format(double number, double #base)
{
StringBuilder format = new StringBuilder();
if(number < 0)
{
format.Append('-');
number = -number;
}
double log = Math.Log(number, #base);
bool frac = false;
double order;
if(log < 0)
{
frac = true;
format.Append(digits[0]);
format.Append('.');
order = 1/#base;
}else{
order = Math.Pow(#base, Math.Floor(log));
}
while(number != 0 || order >= 1)
{
double digit = Math.Floor(number/order);
if(digit >= #base) break;
number = number-digit*order;
number = Math.Round(number, 15);
if(order < 1 && !frac)
{
format.Append('.');
frac = true;
}
order /= #base;
if(digit >= 10)
{
format.Append((char)('A'+(digit-10)));
}else{
format.Append((char)('0'+digit));
}
}
return format.ToString();
}
Use it like Format(headingAngle, 16). You can also comment out number = Math.Round(number, 15); for more interesting results. ☺
Result is in culture-invariant format. For 135.34375, it returns 87.58.

Categories

Resources