GUID from string - c++

Let's say we have a string
"{GUID}"
wherein GUID is a standard GUID in {}. I need to get a variable of type GUID matching the given string. It is to be done with visual C++ and the version is very old (6.0) if that matters.
Firstly I tried to use GUIDFromString function but wasn't able to get it imported so found out about UuidFromString. But I am really stuck at all these casts from unsigned char to char etc, having no C++ background it is very hard. Maybe some one will be so kind to help me with this. Thanks.

GUID refers to some unique identification number, which can be generated using some algorithm - you can find some descriptions on Microsoft's algorithms - where they try to pick up timestamp, network card number, and on one, and mix up into one unique GUID.
What I have checked - noone prevents you of creating your own "unique" generation algorithm - but you need to somehow ensure that your unique generation algorithm won't collide with existing algorithms, which is highly unlikely. Also GUID's generated by your algorithm should not also collide with your own GUID's.
While browsing internet I have found some approaches to generate such guid - for example - Microsoft Office: http://support.microsoft.com/kb/2186281
When generating GUID from Strings, you can use either String.GetHashCode32 or even calculate for example 20 byte sha-1 hash over string. (First one is easier, but second creates more bytes to use for GUID).
And then start to fill in GUID, as much as it requires it.
Here is some demo code which let's you get to the idea:
using System;
class Program
{
/// <summary>
/// http://stackoverflow.com/questions/53086/can-i-depend-on-the-values-of-gethashcode-to-be-consistent
///
/// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static unsafe int GetHashCode32(string s)
{
fixed (char* str = s.ToCharArray())
{
char* chPtr = str;
int num = 0x15051505;
int num2 = num;
int* numPtr = (int*)chPtr;
for (int i = s.Length; i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
}
/// <summary>
/// Generates new product code for particular product / install package.
/// </summary>
/// <param name="productName">Logical product name for which to generate</param>
/// <param name="productVersion">Product version in form "1.0.0"</param>
/// <returns></returns>
static public String GenerateProductCode( String productName, String productVersion )
{
String[] vparts = productVersion.Split(".".ToCharArray());
int[] verParts = new int [3] { 1, 0, 0 };
int i = 0;
foreach( String v in vparts )
{
Int32.TryParse(v, out verParts[i++] );
if( i >= 3 ) break;
}
//
// "MyCompanyName", "1.0.2" will generate guid like this: {F974DC1F-0001-0000-0002-10009CD45A98}
// ^ Hash over manufacturer name - "MyCompanyName"
// ^ Version - "<major>-<minor>-<build>" in hexadecimal
// ^ 1 as for 64 bit.
// ^000 - just reserved for future needs
// ^ Hash over product name
//
// See also similar generation schemes - http://support.microsoft.com/kb/2186281.
//
String newGuid = String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-1000{4:X8}", GetHashCode32("MyCompanyName"), verParts[0], verParts[1], verParts[2], GetHashCode32(productName));
newGuid = "{" + newGuid + "}";
return newGuid;
}
static void Main()
{
String s = GenerateProductCode("MyProduct", "1.0.2");
Console.WriteLine(s);
}
}
Will print out:
{F974DC1F-0001-0000-0002-10003618D1E1}
But in similar manner you can generate GUIDs in C++ as well - use sprintf() most probably.
Here is .NET compatible function for converting String into hash code:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int GetHashCode32( const wchar_t* ps )
{
int num = 0x15051505;
int num2 = num;
const wchar_t* s = ps;
const char* chPtr=(const char*) ps;
size_t numBuff = wcslen((wchar_t*) chPtr) * 2;
int* numPtr = (int*)chPtr;
for (int i = wcslen(s); i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
void GetHash(const wchar_t* p)
{
printf("'%S' = %08X", p, GetHashCode32(p));
printf("\r\n");
}
void main(void)
{
GetHash(L"testing");
GetHash(L"MainClass::" __FUNCTIONW__);
GetHash(L"1");
GetHash(L"");
}

Okay, the problem was in include and libs. You need to include <Rpc.h> and link the RPC library:
#pragma comment (lib, "Rpcrt4.lib")
And than you can use UuidFromString function. Just note that you don't need to include { and } in your string representation.

Related

Debug Assertion Failed error when accessing function in DLL

I'm currently learning how to create a C++ library to be referenced in other projects, and I am running into an issue with a "Debug Assertion Failed" error: is_block_type_valid(header-> _block_use). I followed the walkthrough shown here: Create and use your own Dynamic Link Library. Oddly, I am getting the expected answer if I just ignore the error.
My DLL currently only has one function:
cpp:
int calculate_crc(std::string msg)
{
std::vector<std::string> msg_vector = [](std::string& msg1) {
std::string next;
std::vector<std::string> result;
// for each char in string
for (std::string::const_iterator it = msg1.begin(); it != msg1.end(); it++)
{
// if we hit a terminal char
if (*it == ' ')
{
if (!next.empty())
{
// add them to the result vector
result.push_back(next);
next.clear();
}
}
else
{
next += *it;
}
}
if (!next.empty())
{
result.push_back(next);
}
return result;
} (msg);
int crcReg = 0xFFFF;
// iterate through each element in msgVector
for (auto&& element : msg_vector)
{
// step 2: xor operation performed on byte of msg and CRC register
crcReg ^= [](std::string hex) {
std::map<char, int> map;
map['0'] = 0;
map['1'] = 1;
map['2'] = 2;
map['3'] = 3;
map['4'] = 4;
map['5'] = 5;
map['6'] = 6;
map['7'] = 7;
map['8'] = 8;
map['9'] = 9;
map['a'] = 10;
map['b'] = 11;
map['c'] = 12;
map['d'] = 13;
map['e'] = 14;
map['f'] = 15;
return map[hex[1]] + (map[hex[0]] * 16);
} (element);
// step 3-5 are repeated until 8 bit shifts
for (int i = 0; i < 8; i++)
{
int crcCopy = crcReg;
crcReg >>= 1;
if ((crcCopy & 1) == 0)
continue;
else
crcReg ^= 0xA001;
}
}
return crcReg;
}
h:
#pragma once
#ifdef OMRONLIBRARY_EXPORTS
#define OMRONLIBRARY_API __declspec(dllexport)
#else
#define OMRONLIBRARY_API __declspec(dllimport)
#endif
#include <iostream>
extern "C" OMRONLIBRARY_API int calculate_crc(const std::string msg);
std::string is not a safe type to use in a DLL function parameter. Non-POD types should never be passed over a DLL boundary, unless they are type-erased (such as by using a void* pointer) and are only ever accessed directly by code on one side of the boundary and not the other side.
Assuming the caller is even using C++ at all (C-style DLLs can be used in non-C/C++ languages), it may be using a different std::string implementation. Or it may be using a different C++ compiler, or a different version of the same C++ compiler, or even just different settings for alignment, optimizations, etc. And even if all of that matches the DLL, it will likely be using a different instance of the memory manager that the DLL uses for its std::string implementation.
If you want to pass a string to a DLL function safely, use a C-style char* string instead. You can use std::string inside the DLL, if you want to, eg:
int calculate_crc(const char* msg)
{
use msg as-is ...
or
std::string s_msg = msg;
use s_msg as needed ...
}
extern "C" OMRONLIBRARY_API int calculate_crc(const char* msg);

My code is right but not accepted by Leetcode platoform. (ZigZag Conversion)

It is a leet code problem under the subcategory of string, medium problem.
Query: My program is returning right result for all the test cases at the run time and but when I submit, same test cases are not passing.
I also made a video, click here to watch.
My Code is:
string convert(string s, int numRows) {
int loc_rows = numRows-2;
int i=0;
int a=0,b=0;
int arr[1000][1000];
while(i<s.length())
{
if(a<numRows)
{
arr[a][b] = s[i];
a++;
i++;
}
else if(a>=numRows)
{
if(loc_rows>=1)
{
b++;
arr[loc_rows][b]=s[i];
i++;
loc_rows--;
}
else{
loc_rows=numRows-2;
b++;
a=0;
}
}
}
string result="";
for(int d=0;d<numRows;d++)
{
for(int y=0;y<b+1;y++)
{
char temp = (char)arr[d][y];
if((temp>='a' and temp<='z') or (temp>='A' and temp<='Z') )
result+=temp;
}
}
return result;
}
I believe the issue might be your un-initialised arrays / variables.
Try setting initialising your array: int arr[1000][1000] = {0};
live example failing: https://godbolt.org/z/dxf13P
live example passing: https://godbolt.org/z/8vYEv6
You can't rely on the data that is in these arrays so initialising the values is quite important.
Note: this is because you rely on the empty values in the array to be not a letter ([a-zA-Z]). So that you can re-construct your output with your final loop which attempts to print the characters only. This works the first time around because luckily arr contains 0's in the gaps between your values (or at least not letters). The second time around it contains some junk from the first time around (really - you don't know what this is going to be, but in practise it is probably just the values you left in there from last time). So even though you put in the correct values into arr each time - your final loop finds some of the old non-alpha values in the array - hence your program is incorrect...
Alternatively, we could also use unsigned int to make it just a bit more efficient:
// The following block might slightly improve the execution time;
// Can be removed;
static const auto __optimize__ = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);
return 0;
}();
// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <vector>
#include <string>
static const struct Solution {
using ValueType = std::uint_fast16_t;
static const std::string convert(
const std::string s,
const int num_rows
) {
if (num_rows == 1) {
return s;
}
std::vector<std::string> res(num_rows);
ValueType row = 0;
ValueType direction = -1;
for (ValueType index = 0; index < std::size(s); ++index) {
if (!(index % (num_rows - 1))) {
direction *= -1;
}
res[row].push_back(s[index]);
row += direction;
}
std::string converted;
for (const auto& str : res) {
converted += str;
}
return converted;
}
};

Boost::Regex Segfault (I think)

I'm having an issue with some C++ code that I'm running. Basically, it works fine with most inputs, but with certain inputs it segfaults after my main function returns. This has been... puzzling. I stopped the run at the segfault to get the stack trace, and it returned this:
#0 malloc_consolidate() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4151
#1 _int_free() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4057
#2 boost::re_detail::mem_block_cache::~mem_block_cache()() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0
#3 __cxa_finalize() at /build/eglibc-oGUzwX/eglibc-2.19/stdlib/cxa_finalize.c:56
#4 ??() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0
#5 ??() at
#6 _dl_fini() at /build/eglibc-oGUzwX/eglibc-2.19/elf/dl-fini.c:252
This made me think that I must be doing something wrong with boost regex, but I can't for the life of me figure it out. The way I'm using regex is that users can input a bunch of strings. Those strings could just be normal text, or they could be regular expressions. Because of this, I basically interact with all the inputs as regular expressions. But what if a user gave a string that was intended as plain text but had a character that could be interpreted differently as a regular expression? What I do is go through all plain text input strings and escape all those characters.
Here's the code that I'm working with. This is my main:
int
main(int argc, char * argv[])
{
// Process input arguments
// The desired input is numVertices (int), graph density (double between 0 and 1), halfLoss (double), total loss (double),
// position expanse (double, m), velocity expanse (double, m/s)
int num_vertices;
double graph_density ;
double half_loss;
double total_loss;
double position_expanse;
double velocity_expanse;
if (argc == 1)
{
num_vertices = 48;
graph_density = 1;
half_loss = 200000;
total_loss = 400000;
position_expanse = 400000;
velocity_expanse = 10000;
}
else
{
if (argc != 7)
{
std::cerr << "Need 6 input arguments" << std::endl;
return 1;
}
std::istringstream ss(argv[1]);
num_vertices;
if (!(ss >> num_vertices))
std::cerr << "First input must be an integer" << std::endl;
graph_density = read_double_input(argv[2]);
half_loss = read_double_input(argv[3]);
total_loss = read_double_input(argv[4]);
position_expanse = read_double_input(argv[5]);
velocity_expanse = read_double_input(argv[6]);
}
// Determine how many edges to create
int num_edges = (int) ( (graph_density * num_vertices * (num_vertices - 1)) + 0.5 );
// Create the edges
int edges_created = 0;
std::set<std::pair<int, int> > edge_set;
while (edge_set.size() < num_edges)
{
// Pick a random start vertex and end vertex
int start_vertex = rand() % num_vertices;
int end_vertex = rand() % num_vertices;
// Make sure the start and end vertices are not equal
while (start_vertex == end_vertex)
{
end_vertex = rand() % num_vertices;
}
// Insert the new edge into our set of edges
edge_set.insert(std::pair<int, int>(start_vertex, end_vertex));
}
// Create connection handler
ConnectionHandler conn_handler;
// Create lists for from and to vertices
std::vector<std::string> from_list;
std::vector<std::string> to_list;
// Add connections to from and to lists
for (std::set<std::pair<int, int> >::const_iterator edge_it = edge_set.begin(), end_it = edge_set.end(); edge_it != end_it; ++edge_it)
{
int start_vertex = edge_it->first;
int end_vertex = edge_it->second;
from_list.push_back("Radio" + int_to_string(start_vertex));
to_list.push_back("Radio" + int_to_string(end_vertex));
}
// Read the list into the connection handler
conn_handler.read_connection_list(true, from_list, to_list);
return 0;
}
This code has this ConnectionHandler object that I created. Here's the header for that:
#ifndef CLCSIM_CONNECTIONHANDLER_HPP_
#define CLCSIM_CONNECTIONHANDLER_HPP_
#include <models/network/NetworkTypes.hpp>
#include <generated/xsd/NetworkModelInterfaceConfig.hpp>
namespace clcsim
{
typedef std::map<std::string, std::set<std::string> > ConnectionFilter;
class ConnectionHandler
{
public:
ConnectionHandler();
~ConnectionHandler();
void read_connection_list(const bool is_white_list, const std::vector<std::string> &from_radios, const std::vector<std::string> &to_radios);
private:
ConnectionFilter filter_;
std::set<std::string> from_list_;
std::set<std::string> to_list_;
bool is_white_list_;
};
} // namespace clcsim
#endif // CLCSIM_CONNECTIONHANDLER_HPP_
And here's the source:
#include <models/network/ConnectionHandler.hpp>
#include <oasis/framework/exceptions/ConfigurationException.h>
#include <boost/regex.hpp>
namespace clcsim
{
ConnectionHandler::
ConnectionHandler()
{
}
ConnectionHandler::
~ConnectionHandler()
{
std::cout << "Destructing conn handler" << std::endl;
}
void
ConnectionHandler::
read_connection_list(
const bool is_white_list,
const std::vector<std::string> &from_radios,
const std::vector<std::string> &to_radios)
{
std::cout << "Reading the connection list" << std::endl;
// Make sure the size of both the input vectors are the same
std::size_t from_radio_size = from_radios.size();
std::size_t to_radio_size = to_radios.size();
if (from_radio_size != to_radio_size)
{
throw ofs::ConfigurationException("Error while initializing the "
"Network model: "
"Connections in from/to lists don't align"
);
}
// Create a regular expression/replacement to find all characters in a non-regular expression
// that would be interpreted as special characters in a regular expression. Replace them with
// escape characters
const boost::regex esc("[.$|()\\[\\]{}*+?\\\\]");
const std::string rep("\\\\&");
// Iterate through the specified connections
for (int i = 0; i < from_radio_size; ++i)
{
std::string from_string = boost::regex_replace(from_radios[i], esc, rep, boost::match_default | boost::format_sed);
std::string to_string = boost::regex_replace(to_radios[i], esc, rep, boost::match_default | boost::format_sed);
//std::cout << "From " << from_string << " to " << to_string << std::endl;
filter_[from_string].insert(to_string);
//filter_[from_radios.at(i)].insert(to_radios.at(i));
}
std::cout << "Got here" << std::endl;
}
} // namespace clcsim
Sorry for so much code.
I saw some similar threads related to segfaults with boost::regex. In those examples, the users had really simple code that just created a regex and matched it and ran into an error. It turned out the issue was related to the Boost versioning. I tried to see if I could replicate those sorts of errors, but those simple examples worked just fine for me. So... I'm pretty stumped. I'd really appreciate any help!
For the sake of removing this from the "Unanswered" list, I'm going to post the answer that was provided in the comments instead of here. The OP determined that the suggestion that Boost linked against eglibc was indeed conflicting with the rest of the code linked against glibc. As such, the OP found that upgrading his OS so that eglibc linked libraries were no longer in use fixed the problem.

How to limit a decrement?

There is a initial game difficulty which is
game_difficulty=5 //Initial
Every 3 times if you get it right, your difficulty goes up to infinity but every 3 times you get it wrong, your difficulty goes down but not below 5. So, in this code for ex:
if(user_words==words) win_count+=1;
else() incorrect_count+=1;
if(win_count%3==0) /*increase diff*/;
if(incorrect_count%3==0) /*decrease difficulty*/;
How should I go about doing this?
Simple answer:
if(incorrect_count%3==0) difficulty = max(difficulty-1, 5);
But personally I would wrap it up in a small class then you can contain all the logic and expand it as you go along, something such as:
class Difficulty
{
public:
Difficulty() {};
void AddWin()
{
m_IncorrectCount = 0; // reset because we got one right?
if (++m_WinCount % 3)
{
m_WinCount = 0;
++m_CurrentDifficulty;
}
}
void AddIncorrect()
{
m_WinCount = 0; // reset because we got one wrong?
if (++m_IncorrectCount >= 3 && m_CurrentDifficulty > 5)
{
m_IncorrectCount = 0;
--m_CurrentDifficulty;
}
}
int GetDifficulty()
{
return m_CurrentDifficulty;
}
private:
int m_CurrentDifficulty = 5;
int m_WinCount = 0;
int m_IncorrectCount = 0;
};
You could just add this as a condition:
if (user words==words) {
win_count += 1;
if (win_count %3 == 0) {
++diff;
}
} else {
incorrect_count += 1;
if (incorrect_count % 3 == 0 && diff > 5) {
--diff
}
}
For example:
if(win_count%3==0) difficulty++;
if(incorrect_count%3==0 && difficulty > 5) difficulty--;
This can be turned into a motivating example for custom data types.
Create a class which wraps the difficulty int as a private member variable, and in the public member functions make sure that the so-called contract is met. You will end up with a value which is always guaranteed to meet your specifications. Here is an example:
class Difficulty
{
public:
// initial values for a new Difficulty object:
Difficulty() :
right_answer_count(0),
wrong_answer_count(0),
value(5)
{}
// called when a right answer should be taken into account:
void GotItRight()
{
++right_answer_count;
if (right_answer_count == 3)
{
right_answer_count = 0;
++value;
}
}
// called when a wrong answer should be taken into account:
void GotItWrong()
{
++wrong_answer_count;
if (wrong_answer_count == 3)
{
wrong_answer_count = 0;
--value;
if (value < 5)
{
value = 5;
}
}
}
// returns the value itself
int Value() const
{
return value;
}
private:
int right_answer_count;
int wrong_answer_count;
int value;
};
And here is how you would use the class:
Difficulty game_difficulty;
// six right answers:
for (int count = 0; count < 6; ++count)
{
game_difficulty.GotItRight();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// three wrong answers:
for (int count = 0; count < 3; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// one hundred wrong answers:
for (int count = 0; count < 100; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
Output:
7
6
5
Once you have a firm grasp on how such types are created and used, you can start to look into operator overloading so that the type can be used more like a real int, i.e. with +, - and so on.
How should I go about doing this?
You have marked this question as C++. IMHO the c++ way is to create a class encapsulating all your issues.
Perhaps something like:
class GameDifficulty
{
public:
GameDifficulty () :
game_difficulty (5), win_count(0), incorrect_count(0)
{}
~GameDifficulty () {}
void update(const T& words)
{
if(user words==words) win_count+=1;
else incorrect_count+=1;
// modify game_difficulty as you desire
if(win_count%3 == 0)
game_difficulty += 1 ; // increase diff no upper limit
if((incorrect_count%3 == 0) && (game_difficulty > 5))
game_difficulty -= 1; //decrease diff;
}
inline int gameDifficulty() { return (game_difficulty); }
// and any other access per needs of your game
private:
int game_difficulty;
int win_count;
int incorrect_count;
}
// note - not compiled or tested
usage would be:
// instantiate
GameDiffculty gameDifficulty;
// ...
// use update()
gameDifficulty.update(word);
// ...
// use access
gameDifficulty.gameDifficulty();
Advantage: encapsulation
This code is in one place, not polluting elsewhere in your code.
You can change these policies in this one place, with no impact to the rest of your code.

All possible combinations(with repetition) as values in array using recursion

I'm trying to solve a problem in which I need to insert math operations(+/- in this case) between digits or merge them to get a requested number.
For ex.: 123456789 => 123+4-5+6-7+8-9 = 120
My concept is basically generating different combinations of operation codes in array and calculating the expression until it equals some number.
The problem is I can't think of a way to generate every possible combination of math operations using recursion.
Here's the code:
#include <iostream>
#include <algorithm>
using namespace std;
enum {noop,opplus,opminus};//opcodes: 0,1,2
int applyOp(int opcode,int x, int y);
int calculate(int *digits,int *opcodes, int length);
void nextCombination();
int main()
{
int digits[9] = {1,2,3,4,5,6,7,8,9};
int wantedNumber = 100;
int length = sizeof(digits)/sizeof(digits[0]);
int opcodes[length-1];//math symbols
fill_n(opcodes,length-1,0);//init
while(calculate(digits,opcodes,length) != wantedNumber)
{
//recursive combination function here
}
return 0;
}
int applyOp(int opcode,int x, int y)
{
int result = x;
switch(opcode)
{
case noop://merge 2 digits together
result = x*10 + y;
break;
case opminus:
result -= y;
break;
case opplus:
default:
result += y;
break;
}
return result;
}
int calculate(int *digits,int *opcodes, int length)
{
int result = digits[0];
for(int i = 0;i < length-1; ++i)//elem count
{
result = applyOp(opcodes[i],result,digits[i+1]);//left to right, no priority
}
return result;
}
The key is backtracking. Each level of recursion handles
a single digit; in addition, you'll want to stop the recursion
one you've finished.
The simplest way to do this is to define a Solver class, which
keeps track of the global information, like the generated string
so far and the running total, and make the recursive function
a member. Basically something like:
class Solver
{
std::string const input;
int const target;
std::string solution;
int total;
bool isSolved;
void doSolve( std::string::const_iterator pos );
public:
Solver( std::string const& input, int target )
: input( input )
, target( target )
{
}
std::string solve()
{
total = 0;
isSolved = false;
doSolve( input.begin() );
return isSolved
? solution
: "no solution found";
}
};
In doSolve, you'll have to first check whether you've finished
(pos == input.end()): if so, set isSolved = total == target
and return immediately; otherwise, try the three possibilities,
(total = 10 * total + toDigit(*pos), total += toDigit(*pos),
and total -= toDigit(*pos)), each time saving the original
total and solution, adding the necessary text to
solution, and calling doSolve with the incremented pos.
On returning from the recursive call, if ! isSolved, restore
the previous values of total and solution, and try the next
possibility. Return as soon as you see isSolved, or when all
three possibilities have been solved.