Some years back when I was still a beginner at programming, I found some code online that could generate a bruteforce-code given an offset.
So for instance, if I did GetPassword(1) it would return "a", and if I did GetPassword(2) it would return "b" etc.
Every increment of the offset would provide the next possible combination of strings. A minimum and maximum length of the "password to guess" could also be provided.
Now I have no idea where this code is, or what the algorithm is called. I want to implement one myself, since I need it for URL-enshortening purposes. A user generates a URL that I want to look somewhat long these lines: http://fablelane.com/i/abc where "abc" is the code.
You can think of the output from GetPassword as a number in a different base. For example if GetPassword can output upper and lower case alphanumeric then it is in base 62 -> 26 letters + 26 letters + 10 digits.
GetPassword must convert from base 10 to base 62 in this case. You can use a look up array to find the output characters.
You can convert from one base to another by using an algorithm such as this:
Another stackoverflow post
This is base 26 encoding end decoding:
public static string Encode(int number){
number = Math.Abs(number);
StringBuilder converted = new StringBuilder();
// Repeatedly divide the number by 26 and convert the
// remainder into the appropriate letter.
do
{
int remainder = number % 26;
converted.Insert(0, (char)(remainder + 'a'));
number = (number - remainder) / 26;
} while (number > 0);
return converted.ToString();
}
public static int Decode(string number) {
if (number == null) throw new ArgumentNullException("number");
int s = 0;
for (int i = 0; i < number.Length; i++) {
s += (number[i] - 'a');
s = i == number.Length - 1 ? s : s * 26;
}
return s;
}
Related
I have a base-n-converter and I wanted it to output all values in 4 digit blocks (1111 -> 1111, 101 -> 0101, 110101 -> 00110101). For this, I made this piece in vscode to try and make it work.
using System;
namespace Test
{
using static intUtilities;
class Program
{
static void Main(string[] args)
{
string number = "";
int[] wholenumbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(;;)
{
Console.WriteLine("enter binary number");
number = Console.ReadLine();
Console.WriteLine("is number length divisible by 4? " + Contains(wholenumbers, number.Length/4f));
Console.WriteLine(number.Length/4f);
while(!Contains(wholenumbers, number.Length/4f))
{
number = "0" + number;
}
Console.WriteLine(number);
Console.ReadLine();
}
}
}
public class intUtilities
{
public static bool Contains(int[] array, float number)
{
foreach(int i in array)
{
if(i == number)
{
return true;
}
else {return false;}
}
return false;
}
}
}
For inputting 111, I am expecting an output of 0111, which does happen, but if I input 111111, I am expecting 00111111, but there is no output. When executing the while loop, it should catch the moment when numbers.Length / 4 is "2" (which is when therre would be 8 digits) and break the loop, but for some reason, it doesnt and keeps on adding zeros to the string. It even reads out numbers.Length / 4 as "2" at some point but doesnt break the loop. The code only seems to work for a target size of 4 digits, where numbers.Length / 4 would be "1". Is there a way to correct that? Or even an easier workaround?
There are a number of "interesting" issues with this code, but to answer your immediate question, you need to remove the else {return false;} line. This prevents you from searching over every element in the wholeNumbers array - or more specifically, you only query the first element in the wholeNumbers array (which is the value 1) which is why the code only works correctly for the first 4-bit block of binary digits.
In the spirit of your approach, a possible implementation is:
void Main()
{
string number = "";
Console.WriteLine("enter binary number");
number = Console.ReadLine();
while (number.Length % 4 != 0)
{
number = "0" + number;
}
Console.WriteLine(number);
}
The original question ('why doesn't this work') is answered by Phillip Ngan.
Just fyi the correct result can be gotten in a simple calculation without a loop:
void Main
{
Console.WriteLine("enter binary number");
string number = Console.ReadLine();
int padLength = (4 - (number.Length % 4)) % 4;
number = "000".Substring(0, padLength)+number;
Console.WriteLine(number);
}
edit: Just noticed this is simply a variant for the solution proposed by John Glenn.
Or even an easier workaround?
Relying on the usual "round an integer up to the nearest N" of "integer, divide by N, add one and times by N" we can use this to pad the left of the binary string out to the next "multiple of 4" up from the current length
var x= "01111";
var y = x.PadLeft(((x.Length/4)+1)*4, '0');
y is "00001111";
If you don't like all the parentheses you can use precedence to the same effect
.PadLeft(x.Length/4*4+4, '0');
Hopefully most future readers of the code will remember their high school maths lessons 😀
You can use the modulus function to determine the remainder of one number (the string length) divided by another number (4). The entire effect can be shortened to this:
// find how many characters don't fit into a block of four
int leftovers = numbers.Length % 4;
// determine how many numbers to pad
int padding =
(4 - leftovers) // this is the number of characters we have to add to get an even group of 4
% 4; // this will ensure that if leftovers is 0, then instead of padding 4 characters we don't pad any
// pad the string
string displayMe = numbers.PadLeft(numbers.Length + padding, '0');
Because I am writing software which generates SQL with a potentially large number of parameters and records that SQL onto disk, I have an uncommon requirement (perhaps more a curiosity): Generate the shortest possible unique parameter names.
Parameter names follow identifier naming rules which are usually:
First character is alphabetic
Subsequent characters can be alphanumeric or certain other characters, such as an underscore.
Almost anything can be used if quoted (ignored -- a quoted identifier is at least three characters total, e.g. [_])
The SQL generation code knows how many identifiers there are total, so names can be generated based on an integer.
This ended up being more difficult than I anticipated, and the solution less elegant.
I hard-coded invalid values (starting with 0) because they are few and every attempt I made to derive them ended up complicated and slow. I would appreciate ideas on how to make this more elegant. I'll post on CodeReview as well.
Most databases support fewer than 2^16 parameters (a ridiculous number to actually use), but in handling numbers larger than 35027 (also ridiculous) the numbers worked out such that 1 million was a good forced stopping point.
public static String intToDatabaseIdentifier(int number)
{
if(number < 0 || number > 1000000)
throw new ArgumentOutOfRangeException("number");
if(number > 25 && number <= 25 + 10) // Skip 0-9 (modified base 36)
number += 10;
if(number > 971 && number <= 971 + 360) // Skip 0a-09 (modified base 36)
number += 360;
if(number > 35027 && number <= 35027 + 12960) // Skip 0aa-099 (modified base 36)
number += 12960;
var stack = new Stack<char>();
// Base 36 starting with letters rather than numbers
const string characters = "abcdefghijklmnopqrstuvwxyz0123456789";
while(number >= 0) {
stack.Push(characters[number % 36]);
number = number / 36 - 1;
}
return new String(stack.ToArray());
}
Results starting with 0:
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
aa ab ac ad ae af ag ah ai aj aa ab ac ad ae af ag ah ai aj ak al am an ao
ap aq ar as at au av aw ax ay az a0 a1...
Code above produces collisions. Fixed code without collisions and magic numbers.
public static String intToDatabaseIdentifier(int number)
{
const string abcFirst = "abcdefghijklmnopqrstuvwxyz";
const string abcFull = "abcdefghijklmnopqrstuvwxyz0123456789";
if (number < 0 || number > 1000000)
throw new ArgumentOutOfRangeException("number");
var stack = new Stack<char>();
//Get first symbol. We will later reverse string. So last - will be first.
stack.Push(abcFirst[number % abcFirst.Length]);
number = number / abcFirst.Length;
//Collect remaining part
while (number > 0)
{
int index = (number - 1) % abcFull.Length;
stack.Push(abcFull[index]);
number = (number - index) / abcFull.Length;
}
//Reversing to guarantee first non numeric.
return new String(stack.Reverse().ToArray());
}
Timur Mannapov's answer produces results similar to some of my other attempts (except his results don't have the problems noted in comments) in that the progression is not what one would expect, e.g. aa, ba, ca instead of aa, ab, ac:
(call with String.Concat(ToParamName(i)))
// Starts with aa, ba, ba... instead of a, b, c. Probably wouldn't be hard
// to fix but I abandoned this method because it's annoying to call using
// string.Concat(...)
public static IEnumerable<char> ToParamName(int number) {
const string characters = "abcdefghijklmnopqrstuvwxyz0123456789";
yield return characters[number % 26];
number = number / 26;
do {
yield return characters[number % 36];
number = number / 36 - 1;
} while(number >= 0);
}
// Starts with a, b, c...aa, ba, ba but has collisions starting around 960
public static IEnumerable<char> ToParamName(int number) {
const string characters = "abcdefghijklmnopqrstuvwxyz0123456789";
yield return characters[number % 26];
number = number / 26;
while(number > 0) {
yield return characters[number % 36];
number = number / 36 - 1;
}
}
I prefer having the results returned in a more natural order like a..z, aa, ab, ac...a9 (hey, I didn't claim I was being purely practical), but I forgot to mention that in the original post. Timur's answer covers all the original requirements, so I'll mark it correct.
I'll +1 an answer that produces results as described.
I'm looking to use some sort of unique identifier within a .resx file but it does not allow the key to begin with a number. Rather than cycling through GUIDs until I get one that starts with a letter, I'm wondering if there's an alternative UID type that either does not contain numbers or would otherwise meet this requirement.
Any thoughts?
If you just want to create a Guid that starts with a letter, you could do something like this:
var b = Guid.NewGuid().ToByteArray();
b[3] |= 0xF0;
return new Guid(b);
This will always generate a GUID that starts with the hex digit F.
To create a Guid that doesn't contain any numbers you could use something like this:
return new Guid(Guid.NewGuid().ToByteArray()
.Select(b => (byte)(((b % 16) < 10 ? 0xA : b) |
(((b >> 4) < 10 ? 0xA : (b >> 4)) << 4)))
.ToArray());
This will test each hex digit (two per byte) and coerce it to A if it's less than A.
Both the above solutions generate real Guid objects, although the added restrictions do decrease the uniqueness of the resulting GUIDs to some degree (far more so in the second example). If you don't care about the output being actual GUIDs, you can simply remap the hex digits to something else and return the result a string, as others have suggested. FWIW, here's the shortest solution I can think of:
return String.Concat(Guid.NewGuid().ToString("N").Select(c => (char)(c + 17)));
This maps the hex digits 0 through 9 to the characters A through J, and the hex digits A - F to the characters r through w. It also generates a string without any hyphens. It For example:
Before: e58d0f329a2f4615b922ecf53dcd090a
After: vFIuAwDCJrCwEGBFsJCCvtwFDutuAJAr
Of course, you could convert this to all upper or lower case if you don't like the mixed case here.
How about generating a unique number and then prefixing it with a letter? So instead of
1234
You would use
a1234
As long as the algorithm you choose for the identifier guarantees a unique number, this should work just fine. It will also give you the ability to strip out the prefix and work with the identifier as a number again if need be.
You can write and use a psuedorandom sequence generator. Here's one that gives the basic idea:
class RandomLetterSequence {
private static Random r;
private static char MinChar = (char) 0x0061;
private static char MaxChar = (char) 0x007A;
public static string RandomSequence() {
return RandomSequence(32);
}
public static string RandomSequence(int length) {
if (r == null)
r = new Random();
var sb = new StringBuilder();
for (int i = length; i >= 0; i--) {
sb.Append((char)(r.Next(MinChar, MaxChar)));
}
return sb.ToString();
}
}
With this implementation, there are 26^32 possible different sequences that are generated that conform to your requirements:
Similar to GUIDs in terms of collision rate (infinitesimally small)
Contains only letters
Assuming that you don't need it to a be valid Guid (you refer to 'some sort of unique identifier'), just create a string based guid (using Guid.NewGuid().ToString()) then map the first digit to a range of suitable letters e.g. 0=G, 1=H, 2=I etc.
Just write your own GUID-like generator, a valid character would be a-z (you can also use A-Z to increase the number of probabilities).
Generate the new GUID and just replace the characters 0-9 with characters g-p.
#p.s.w.g provided good solution.
You can write his/her recommendations as Extension:
using System;
using System.Linq;
namespace YourApp.Extensions.GuidExtensions
{
public static class Extension
{
public static Guid FirstLetter(this Guid obj)
{
var b = obj.ToByteArray();
b[3] |= 0xF0;
return new Guid(b);
}
public static Guid OnlyLetters(this Guid obj)
{
var ba = obj.ToByteArray();
return new Guid(
ba.Select(b => (byte)(((b % 16) < 10 ? 0xA : b) |
(((b >> 4) < 10 ? 0xA : (b >> 4)) << 4)))
.ToArray()
);
}
}
}
And then use it somewhere in app:
// ...
using YourApp.Extensions.GuidExtensions;
// ...
class SomeClass {
Guid SomeMethodWithFirstLetter() {
return Guid.NewGuid().FirstLetter();
}
Guid SomeMethodWithOnlyLetters() {
return Guid.NewGuid().OnlyLetters();
}
}
I have a task to complete in C#. I have a Subnet Mask: 255.255.128.0.
I need to find the number of bits in the Subnet Mask, which would be, in this case, 17.
However, I need to be able to do this in C# WITHOUT the use of the System.Net library (the system I am programming in does not have access to this library).
It seems like the process should be something like:
1) Split the Subnet Mask into Octets.
2) Convert the Octets to be binary.
3) Count the number of Ones in each Octet.
4) Output the total number of found Ones.
However, my C# is pretty poor. Does anyone have the C# knowledge to help?
Bit counting algorithm taken from:
http://www.necessaryandsufficient.net/2009/04/optimising-bit-counting-using-iterative-data-driven-development/
string mask = "255.255.128.0";
int totalBits = 0;
foreach (string octet in mask.Split('.'))
{
byte octetByte = byte.Parse(octet);
while (octetByte != 0)
{
totalBits += octetByte & 1; // logical AND on the LSB
octetByte >>= 1; // do a bitwise shift to the right to create a new LSB
}
}
Console.WriteLine(totalBits);
The most simple algorithm from the article was used. If performance is critical, you might want to read the article and use a more optimized solution from it.
string ip = "255.255.128.0";
string a = "";
ip.Split('.').ToList().ForEach(x => a += Convert.ToInt32(x, 2).ToString());
int ones_found = a.Replace("0", "").Length;
A complete sample:
public int CountBit(string mask)
{
int ones=0;
Array.ForEach(mask.Split('.'),(s)=>Array.ForEach(Convert.ToString(int.Parse(s),2).Where(c=>c=='1').ToArray(),(k)=>ones++));
return ones
}
You can convert a number to binary like this:
string ip = "255.255.128.0";
string[] tokens = ip.Split('.');
string result = "";
foreach (string token in tokens)
{
int tokenNum = int.Parse(token);
string octet = Convert.ToString(tokenNum, 2);
while (octet.Length < 8)
octet = octet + '0';
result += octet;
}
int mask = result.LastIndexOf('1') + 1;
The solution is to use a binary operation like
foreach(string octet in ipAddress.Split('.'))
{
int oct = int.Parse(octet);
while(oct !=0)
{
total += oct & 1; // {1}
oct >>=1; //{2}
}
}
The trick is that on line {1} the binary AND is in sence a multiplication so multiplicating 1x0=0, 1x1=1. So if we have some hypothetic number
0000101001 and multiply it by 1 (so in binary world we execute &), which is nothig else then 0000000001, we get
0000101001
0000000001
Most right digit is 1 in both numbers so making binary AND return 1, otherwise if ANY of the numbers minor digit will be 0, the result will be 0.
So here, on line total += oct & 1 we add to tolal either 1 or 0, based on that digi number.
On line {2}, instead we just shift the minor bit to right by, actually, deviding the number by 2, untill it becomes 0.
Easy.
EDIT
This is valid for intgere and for byte types, but do not use this technique on floating point numbers. By the way, it's pretty valuable solution for this question.
I have a homework that I just can't figure out how to do. I'm not sure if the teacher wrote it wrong(he is a bad typer) or if there is a way to accomplish the task.
I work in Visual C# 2010 Express - Console Application
My task is to:
Read a four digit integer, such as 5893, from the keyboard and display the digits separated from one another by a tab each. Use both integer division and modulus operator % to pick off each digit. If the user enters 4567, the output looks like:
4567
4 5 6 7
Sure I know how to separate the numbers by using \t as well as reading the input and displaying it to the user. But how am I supposed to 'pick off' each digit with division and the remainder operators? Maybe he means something else, but not sure.
And another question...
How do I make sure that what the user types in is a number and not a letter?
Do I have to use Char.IsLetter, because I couldn't figure out how to use it on a parsed string.
Example:
string number1;
int x;
Console.Write("Please enter a number to calculate: ");
number1 = Console.ReadLine();
x = Int32.Parse(number1);
What method am I supposed to use and where do i put it in? Because now i only get an error and the application shuts down if I try to enter e letter.
The first question is really more about maths than programming. You know what the division and modulus operators do. Think about how you could use them to get the last (least significant) digit. Once you've done that you can apply a similar technique for the 2nd digit (tens) and then the same for hundreds and thousands and so on.
You've already found Char.IsLetter, but there is also Char.IsDigit, which does what you want more directly. You can do this check for one character and what you have is a string of characters. Have a look at a foreach loop.
System.Int32.TryParse() might be a better choice when converting the String.
Yes, your assignment makes sense. Say you have an integer x = 4567. To pick out the digit at position A you would use:
result = (int)((x / (A * 10)) % 10);
The first part of this (x / (A * 10)) "shifts" x to the right. So a value of A = 1 would divide 4567 by 10 which results in 456.7. You then use the modulo operator "%" to pick out the unit part of that number. Finally you convert to an int to remove the fractional part.
Ok, I won't give the whole solution (after all, this is homework ;)).
This code would check if there's four characters in input:
string input;
do
{
input = Console.ReadLine();
if (input.Length != 4)
Console.WriteLine("You have to enter FOUR digits");
} while (input.Length != 4);
This could be one way of checking the digits:
bool isOk = true;
foreach (char c in input.ToArray())
{
if (!Char.IsDigit(c))
{
Console.WriteLine("You have to enter four DIGITS");
isOk = false;
break;
}
}
This approach doesn't deal with math but you could do that just as well:
int num = int.Parse(input);
int tensOfThousands = num / 10000;
int thousands = (num - tensOfThousands) / 1000;
int lastDigit = num % 10;
//the rest of the digits are up to you ;)
For everybody new to C#, the solution can be simpler.
// Variables
int number = 1234;
int remainder;
string s = "";
while (number > 0) {
remainder = number % 10;
s = remainder + "\n" + s;
number /= 10;
}
Console.Write (s);