Hash to string with given character set - r

The usual hash-functions, e.g. from digest create hex output. I want to create a hash with character from a given set, e.g [a-z,0-9]; no strong cryptographic security is required.
Using base64encode on a hashed string comes close, but the character set is fixed in that function.

It is ugly div/mod manipulation for an arbitrary character table, so I decided to use a 32 character table without l 0, O
#include <Rcpp.h>
using namespace Rcpp;
static const std::string base32_chars = "abcdefghijkmnpqrstuvwxyz23456789";
// [[Rcpp::export]]
String encode32(uint32_t hash_int, int length = 7)
{
String res;
std::ostringstream oss;
if (length > 7 || length < 1)
length = 7;
for (int i = 0; i < length; i++) {
oss << base32_chars[hash_int & 31];
hash_int = hash_int >> 5;
}
res = oss.str();
return res;
}
/*** R
print(encode32(digest::digest2int("Hellod")))
*/

Related

Arduino - How to convert double to HEX format

I have an arudino code where I get some temperature reading:
double c1 = device.readCelsius();
Serial.println(c1);
The output is for example: 26.23
What I need is to get this converted to 2623 and then to HEX value so I get: 0x0A3F
Any clue?
I guess your float values always get numbers up to two decimal. So, you can just multiply the value which you read from sensor with a 100.
decimalValue = 100 * c1
And then you can use this small code for converting the decimal value to HEX.
Thanks to GeeksforGeeks
You can find the full tutorial here
// C++ program to convert a decimal
// number to hexadecimal number
#include <iostream>
using namespace std;
// function to convert decimal to hexadecimal
void decToHexa(int n)
{
// char array to store hexadecimal number
char hexaDeciNum[100];
// counter for hexadecimal number array
int i = 0;
while (n != 0) {
// temporary variable to store remainder
int temp = 0;
// storing remainder in temp variable.
temp = n % 16;
// check if temp < 10
if (temp < 10) {
hexaDeciNum[i] = temp + 48;
i++;
}
else {
hexaDeciNum[i] = temp + 55;
i++;
}
n = n / 16;
}
// printing hexadecimal number array in reverse order
for (int j = i - 1; j >= 0; j--)
cout << hexaDeciNum[j];
}
// Driver program to test above function
int main()
{
int n = 2545;
decToHexa(n);
return 0;
}

Is it possible to dynamically load files inside a cppFunction in R?

I'm working on a problem in which I would greatly benefit from being able to load vectors that are saved in disk dynamically inside a loop as this allows me to skip calculating the vectors on the fly (in my actual process one vector is used many times and the collection of vectors as a matrix is too big to have in memory all at once). As a simplified example, lets say that we have the vectors stored in a directory with path prefix (each in its own file). The names of these files are vec0.txt, vec1.txt, vec2.txt, ... etc. We wish to sum all the numbers of all specified vectors in the inclusive range start-end. The size of all vectors is known and is always the same. I thought of something like:
library(Rcpp)
cppFunction('int sumvectors(int start, int end, string prefix, int size) {
int i;
int j;
int arr[size];
int sum=0;
for (i=start; i <= end; i++) {
// Here you would construct the path to the file paste0(prefix, vec, i, ".txt")
// Then load it and put it into an array
for (j=0; j <= size; j++) {
sum+=arr[j];
}
}
return sum;
}')
Is something like this even possible? I'm ok at R but never worked with C or C++ so I don't really even know if this is even doable with Rcpp
Yes, this is certainly possible. If your numbers are written in plain text files separated by spaces like this:
C://Users/Administrator/vec1.txt
5.1 21.4 563 -21.2 35.6
C://Users/Administrator/vec2.txt
3 6 8 7 10 135
Then you can write the following function:
cppFunction("
std::vector<float> read_floats(const std::string& path)
{
std::vector<float> result;
for(int i = 1; i < 3; ++i)
{
std::string file_path = path + std::to_string(i) + \".txt\";
std::ifstream myfile(file_path.c_str(), std::ios_base::in);
float a, vec_sum = 0;
std::vector<float> vec;
while(myfile >> a)
{
vec.push_back(a);
}
for(std::vector<float>::iterator it = vec.begin(); it != vec.end(); ++it)
{
vec_sum += *it;
}
result.push_back(vec_sum);
}
return result;
}", include = c("#include<string>", "#include<fstream>", "#include<vector>"))
Which creates an R function that allows you to do this:
read_floats("c:/Users/Administrator/vec")
#> [1] 603.9 169.0
Which you can confirm is the sum of the numbers in each file.

Convert individual Rcpp::IntegerVector element to a character

I have to convert individual elements of Rcpp::IntegerVector into their string form so I can add another string to them. My code looks like this:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::String int_to_char_single_fun(int x){
// Obtain environment containing function
Rcpp::Environment base("package:base");
// Make function callable from C++
Rcpp::Function int_to_string = base["as.character"];
// Call the function and receive its list output
Rcpp::String res = int_to_string(Rcpp::_["x"] = x); // example of original param
// Return test object in list structure
return (res);
}
//[[Rcpp::export]]
Rcpp::CharacterVector add_chars_to_int(Rcpp::IntegerVector x){
int n = x.size();
Rcpp::CharacterVector BASEL_SEG(n);
for(int i = 0; i < n; i++){
BASEL_SEG[i] = "B0" + int_to_char_single_fun(x[i]);
}
return BASEL_SEG;
}
/*** R
int_vec <- as.integer(c(1,2,3,4,5))
BASEL_SEG_char <- add_chars_to_int(int_vec)
*/
I get the following error:
no match for 'operator+'(operand types are 'const char[3]' and 'Rcpp::String')
I cannot import any C++ libraries like Boost to do this and can only use Rcpp functionality to do this. How do I add string to integer here in Rcpp?
We basically covered this over at the Rcpp Gallery when we covered Boost in an example for lexical_cast (though that one went the other way). So rewriting it quickly yields this:
Code
// We can now use the BH package
// [[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <boost/lexical_cast.hpp>
using namespace Rcpp;
using boost::lexical_cast;
using boost::bad_lexical_cast;
// [[Rcpp::export]]
std::vector<std::string> lexicalCast(std::vector<int> v) {
std::vector<std::string> res(v.size());
for (unsigned int i=0; i<v.size(); i++) {
try {
res[i] = lexical_cast<std::string>(v[i]);
} catch(bad_lexical_cast &) {
res[i] = "(failed)";
}
}
return res;
}
/*** R
lexicalCast(c(42L, 101L))
*/
Output
R> Rcpp::sourceCpp("/tmp/lexcast.cpp")
R> lexicalCast(c(42L, 101L))
[1] "42" "101"
R>
Alternatives
Because converting numbers to strings is as old as computing itself you could also use:
itoa()
snprintf()
streams
and probably a few more I keep forgetting.
As others have pointed out, there are several ways to do this. Here are two very straightforward approaches.
1. std::to_string
Rcpp::CharacterVector add_chars_to_int1(Rcpp::IntegerVector x){
int n = x.size();
Rcpp::CharacterVector BASEL_SEG(n);
for(int i = 0; i < n; i++){
BASEL_SEG[i] = "B0" + std::to_string(x[i]);
}
return BASEL_SEG;
}
2. Creating a new Rcpp::CharacterVector
Rcpp::CharacterVector add_chars_to_int2(Rcpp::IntegerVector x){
int n = x.size();
Rcpp::CharacterVector BASEL_SEG(n);
Rcpp::CharacterVector myIntToStr(x.begin(), x.end());
for(int i = 0; i < n; i++){
BASEL_SEG[i] = "B0" + myIntToStr[i];
}
return BASEL_SEG;
}
Calling them:
add_chars_to_int1(int_vec) ## using std::to_string
[1] "B01" "B02" "B03" "B04" "B05"
add_chars_to_int2(int_vec) ## converting to CharacterVector
[1] "B01" "B02" "B03" "B04" "B05"

Rcpp memory management

I am trying to convert some character data to numeric as below. The data will come with special caracters so I have to get them out. I convert the data to std:string to search for the special caracters. Dos it creates a new variable in memory? I want to know if there is a better way to do it.
NumericVector converter_ra_(Rcpp::RObject x){
if(x.sexp_type() == STRSXP){
CharacterVector y(x);
NumericVector resultado(y.size());
for(unsigned int i = 0; i < y.size(); i++){
std::string ra_string = Rcpp::as<std::string>(y[i]);
//std::cout << ra_string << std::endl;
double t = 0;
int base = 0;
for(int j = (int)ra_string.size(); j >= 0; j--){
if(ra_string[j] >= 48 && ra_string[j] <= 57){
t += ((ra_string[j] - '0') * base_m[base]);
base++;
}
}
//std::cout << t << std::endl;
resultado[i] = t;
}
return resultado;
}else if(x.sexp_type() == REALSXP){
return NumericVector(x);
}
return NumericVector();
}
Does it creates a new variable in memory?
If the input object actually is a numeric vector (REALSXP) and you are simply returning, e.g. as<NumericVector>(input), then no additional variables are created. In any other case new memory will, of course, need to be allocated for the returned object. For example,
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector demo(RObject x) {
if (x.sexp_type() == REALSXP) {
return as<NumericVector>(x);
}
return NumericVector::create();
}
/*** R
y <- rnorm(3)
z <- letters[1:3]
data.table::address(y)
# [1] "0x6828398"
data.table::address(demo(y))
# [1] "0x6828398"
data.table::address(z)
# [1] "0x68286f8"
data.table::address(demo(z))
# [1] "0x5c7eea0"
*/
I want to know if there is a better way to do it.
First you need to define "better":
Faster?
Uses less memory?
Fewer lines of code?
More idiomatic?
Personally, I would start with the last definition since it often entails one or more of the others. For example, in this approach we
Define a function object Predicate that relies on the standard library function isdigit rather than trying to implement this locally
Define another function object that uses the erase-remove idiom to eliminate characters as determined by Predicate; and if necessary, uses std::atoi to convert what remains into a double (again, instead of trying to implement this ourselves)
Uses an Rcpp idiom -- the as converter -- to convert the STRSXP to a std::vector<std::string>
Calls std::transform to convert this into the result vector
#include <Rcpp.h>
using namespace Rcpp;
struct Predicate {
bool operator()(char c) const
{ return !(c == '.' || std::isdigit(c)); }
};
struct Converter {
double operator()(std::string s) const {
s.erase(
std::remove_if(s.begin(), s.end(), Predicate()),
s.end()
);
return s.empty() ? NA_REAL : std::atof(s.c_str());
}
};
// [[Rcpp::export]]
NumericVector convert(RObject obj) {
if (obj.sexp_type() == REALSXP) {
return as<NumericVector>(obj);
}
if (obj.sexp_type() != STRSXP) {
return NumericVector::create();
}
std::vector<std::string> x = as<std::vector<std::string> >(obj);
NumericVector res(x.size(), NA_REAL);
std::transform(x.begin(), x.end(), res.begin(), Converter());
return res;
}
Testing this for minimal functionality,
x <- c("123 4", "abc 1567.35 def", "abcdef", "")
convert(x)
# [1] 1234.00 1567.35 NA NA
(y <- rnorm(3))
# [1] 1.04201552 -0.08965042 -0.88236960
convert(y)
# [1] 1.04201552 -0.08965042 -0.88236960
convert(list())
# numeric(0)
Will this be as performant as something hand-written by a seasoned C or C++ programmer? Almost certainly not. However, since we used library functions and common idioms, it is reasonably concise, likely to be bug-free, and the intention is fairly evident even at a quick glance. If you need something faster then there are probably a handful of optimizations to be made, but there's no need to begin on that premise without benchmarking and profiling first.

pointer to arrays of struct

struct a{
double array[2][3];
};
struct b{
double array[3][4];
};
void main(){
a x = {{1,2,3,4,5,6}};
b y = {{1,2,3,4,5,6,7,8,9,10,11,12}};
}
I have two structs, inside which there are two dim arrays with different sizes. If I want to define only one function, which can deal with both x and y (one for each time), i.e., the function allows both x.array and y.array to be its argument. How can I define the input argument? I think I should use a pointer.... But **x.array seems not to work.
For example, I want to write a function PrintArray which can print the input array.
void PrintArray( ){}
What should I input into the parenthesis? double ** seems not work for me... (we can let dimension to be the PrintArray's argument as well, telling them its 2*3 array)
Write a function that takes three parameters: a pointer, the number of rows, and the number of columns. When you call the function, reduce the array to a pointer.
void PrintArray(const double *a, int rows, int cols) {
int r, c;
for (r = 0; r < rows; ++r) {
for (c = 0; c < cols; ++c) {
printf("%3.1f ", a[r * cols + c]);
}
printf("\n");
}
}
int main(){
struct a x = {{{1,2,3},{4,5,6}}};
struct b y = {{{1,2,3,4},{5,6,7,8},{9,10,11,12}}};
PrintArray(&x.array[0][0], 2, 3);
PrintArray(&y.array[0][0], 3, 4);
return 0;
}

Resources