I want to generate folders using combinations of given characters i.e. 8 character text with combination of characters: abcdefghijklmnopqrstuvwxyz1234567890. For the 8 characters combinations there are 2821109907456 possibilities. I want to group these by range of 10,000.
I need to put these folders in relevant range folders i.e. 'aaaaaaa1 - aaaaaaa9' is a range of 9 combinations and a folder 'aaaaaaa3' will be created in this range folder.
I want to use c# code, give my method a folder name i.e. 'aaaaaaa3' and be returned the relevant folder range i.e. 'aaaaaa1 - aaaaaaa9' where it should be saved.
Question: I need c# code to do this!
From the beginning, it looks like we're going to need to compute ranges of alphanumeric sequences, which means converting them to numbers and back. An all-purpose base converter seems like the first logical step:
/// <summary>
/// Provides conversion between long integers and custom number bases.
/// </summary>
public class BaseConverter
{
private string _characterSet;
/// <summary>
/// Creates a new BaseConverter.
/// </summary>
/// <param name="characterSet">The characters in the custom base, in
/// increasing order of value.</param>
public BaseConverter(string characterSet =
"0123456789abcdefghijklmnopqrstuvwxyz")
{
_characterSet = characterSet;
}
/// <summary>
/// Converts a number in the custom base system to a long.
/// </summary>
/// <param name="value">The custom base number to convert.</param>
/// <returns>The long form of the custom base number.</returns>
public long StringToLong(string value)
{
if (value == Convert.ToString(_characterSet[0])) return 0;
long val = 0;
string text = value[0] == '-' ? value.Substring(1,
value.Length - 1) : value;
for (int i = text.Length, power = 0; i != 0; i--, power++)
{
val += (long)Math.Round((_characterSet.IndexOf(text[i-1]) *
Math.Pow(_characterSet.Length, power)));
}
return value[0] == '-' ? -val : val;
}
/// <summary>
/// Converts a long to the custom base system.
/// </summary>
/// <param name="value">The long to convert.</param>
/// <returns>The custome base number version of the long.</returns>
public string LongToString(long value)
{
if (value == 0) return Convert.ToString(_characterSet[0]);
long number = value.Abs();
int remainder;
StringBuilder text = new StringBuilder((int)Math.Round(
Math.Log(long.MaxValue, (double)_characterSet.Length)) +
value < 0 ? 1 : 0);
while (number != 0)
{
remainder = (int)(number % _characterSet.Length);
text.Insert(0, _characterSet[remainder]);
number -= remainder;
number /= _characterSet.Length;
}
if (value < 0) text.Insert(0, "-");
return text.ToString();
}
Then, you'll need the code to compute your ranges:
///<summary>
///Computes numeric ranges using a BaseConverter.
///</summary>
public class NumericRangeFactory
{
private long _min, _length;
private BaseConverter _converter;
//creates a new NumericRangeFactory
//converter - the BaseConverter that defines the number system
//being used
//min - the smallest value in an acceptable range
//length - the number of values in a single range
public NumericRangeFactory(BaseConverter converter, long min,
long length)
{
_converter = converter; _min = min; _length = length;
}
public NumericRangeFactory(BaseConverter converter, string min,
long length) : this(converter.StringToLong(min), length) {}
//returns an array of long containing the min and max of the
//range that contains value
public long[] GetLongRange(long value)
{
long min = _length * (value / _length); //todo: fix non-zero _min case
return new long[] { min, min + length - 1 };
}
public long[] GetLongRange(string value)
{
return GetLongRange(_converter.StringToLong(value));
}
//returns an array of string containing the min and max of
//the range that contains value
public string[] GetStringRange(long value)
{
long[] range = GetLongRange(value);
return new string[] {_converter.LongToString(range[0]),
_converter.LongToString(range[1])};
}
public string[] GetStringRange(string value)
{
return GetStringRange(_converter.StringToLong(value));
}
}
Finally, tie the BaseConverter and NumericRangeFactory classes together to solve the problem with this sample static method:
public static string GetFolderRange(string folderName)
{
BaseConverter converter = new BaseConverter();
NumericRangeFactory rangeFactory = new NumericRangeFactory(converter,
"aaaaaaa0", 9);
string[] range = rangeFactory.GetStringRange(folderName);
return range[0] + "-" + range[1];
}
I haven't tested this, but I think the concept is solid.