I need to send a request to a quote server. Each request should have a distinctive request number (unsigned int) so that when quotes returned with that attached request number I will know to which symbol those quotes belong. Is there any special chars encoding for this type of cases ? E.g. "A" is 13 and "B" is 14, so for "BA" symbol my request number will be 1413.
Will the characters always be capitals A-Z? If so, something simple like this will convert it in the manner that you've described:
var symbol = "BA";
var encoded = symbol.Aggregate(0u, (acc, c) => (uint)(acc * 100 + c - 'A' + 13));
As for mapping the chars directly to a uint, can you guarantee that the symbols are 6 characters or fewer? If not, then there are more possible symbol values than possible uint values.
In any event, the point of a request number is not to encode information about the request; rather, you should keep a dictionary of request numbers (as keys) and information about what to do with the response (as values). With your approach, if you have more than one request for the same symbol, you would end up with different requests that share the same request number.
For example, if you want to map the response to a symbol, you could do this:
private Dictionary<uint, string> _requests = new Dictionary<int, string>();
private uint _requestNumber = 0;
void SendRequest(string symbol)
{
uint currentRequestNumber = _requestNumber++;
_requests[currentRequestNumber] = symbol;
//... send request using currentRequestNumber
}
void ReceiveResponse(Response response)
{
string symbol = _requests[response.RequestNumber];
_requests.Remove(response.RequestNumber);
//...do something with the response...
}
This is not thread safe; it's just a sketch to illustrate the idea.
To answer the question as asked, if the range of possible symbol values is small enough, you could take the approach you outline in your question, where each character maps to a 2-digit number, and you simply concatenate these numbers. I'm not aware of an existing system that uses this approach.
This approach wastes many uint values that cannot correspond to any symbol. For example, if A
is 10, and Z
is 35, and \
is 36, then these ranges are wasted: 0 to 9, 37-1009, 1037-1109, etc.
Another option would be to interpret the symbol as a base-27 number (with 'A'
to 'Z'
plus '\'
as valid digits) and convert it to base 10.
If you would like some sample code, please give some more information about the range of possible symbol values.
mySymbol.GetHashCode()
:- - Eric J. 2012-04-04 02:27
Assuming A = 13, B = 14, ..., Z = 38
you can write a simple function that does this conversion for you. Something like:
uint output = 0;
foreach (char c in inpStr) {
output = output * 100 + (13 + c - 'A');
}
return output;
Where inpStr = "BA" in your example.
If your symbols are always upper case letters, you can create a mapping something like this:
uint result = 0;
uint power = 1;
for (int i=0; i < input.Length; i++)
{
uint digitValue = power * (input[i] - 'A');
result += digitValue;
power *= 26;
}
This effectively considers your symbol to be a base-26 number (digits are 'A' through 'Z') and converts it to base-10, with the "ones" digit furthest to the left (reverse of standard numbers, but irrelevant because it's internally consistent). If you wanted to treat the digits as ones-digit-on-the-left, you would just need to modify input[i]
to be input[input.Length - i]
.
Update Given your clarification that the '/' symbol is also allowed, just convert the "base" from 26 to 27 and order "/" just above "Z" (arbitrary, but easier). You will need to test if input[i] is '/' and assign the result power * 27 for that case.