Archive

Posts Tagged ‘string’

Alternate letters of several strings to create a new one

October 16, 2013 No comments

When hashing a password, it is recommended not only hashing the password. Concatenate the password string with other strings (or salt value), so those passwords won’t be broken using hashes databases. This is another technique to include salt to our passwords, or even a method to generate passwords.

This function will alternate letters of some given strings and put them in a new one. So if we take these two words: “Binary” and “Poetry”, it will generate “BPioneatrryy” (I’m sure you haven’t read that :) )

Lets see the function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  function letterAlternate($strs)
  {
    $n_strs = count ($strs);

    if ($n_strs==1)        /* If there is only one string, return it */
      return $strs[0];

    /* Count the characters of every string and store them */
    $chars_str=array();
    for ($i=0; $i<$n_strs; $i++)
      $chars_str[$i]=strlen($strs[$i]);

    $max_str = max ($chars_str); /* The larges string determines when we stop */
    $res='';

    for ($j=0; $j<$max_str; $j++)
      {

    for ($i=0; $i<$n_strs; $i++)
      {
        /* If the string isn't finished, we'll add the character to the string */
        if ($j<$chars_str[$i])
          $res.=$strs[$i][$j];
      }
      }

    return $res;
  }

echo letterAlternate (array("Binary", "Poetry", "Gaspar", "Fernandez", "Programming", "Blog", "Free", "Software"));

We will get: BPGFPBFSioaerlronesrooefatpnggetrraarwyyrnaadmremezing

Replace substrings inside strings in C++

October 12, 2013 No comments

One of the most useful tools when programming is searching and replacing text from a string. In other words, searching for substrings inside a bigger string and replacing them with other substrings. For example, we can use templates to generate a message or our desired output, we just have to replace some keywords located inside our template (our big string) with our generated data.

We will do it calling standard string methods to find this substring and then replacing it with another one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>

using namespace std;

int main()
{
  string original = "Going to sleep. Everyone knows past 12 we must go to sleep.";

  string::size_type pos = original.find("sleep", 0);

  cout << "Original string: "<<original<<endl;

  if (pos < string::npos)
    original.replace(pos, string("sleep").length(), "code");

  cout << "Resulting string: "<<original<<endl;
  return 0;
}

To compile:

$g++ -o replace replace.cpp

In this case, we use method find to search for the position where the substring “sleep” starts. If the string is not found, it returns string::npos (a constant), but if it is, we will replace it with the word “code”, so we will have to say the start position inside original, and the size of the substring we want to replace.

Now, what we want is to replace all occurrences of “sleep” inside the string, so we just have to loop find() and replace() while we are still finding the substring, this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string>

using namespace std;

int main()
{
  string original = "Going to sleep. Everyone knows past 12 we must go to sleep.";

  string::size_type pos = 0;

  // No we are using these variables with the substring to be replaced and the replacement.
  string fromStr = "sleep";
  string toStr = "code";

  cout << "Original: "<<original<<endl;

  // Loop while finding substrings
  while ((pos = original.find(fromStr, pos)) < string::npos)
    {
      original.replace(pos, fromStr.length(), toStr);
      pos+=toStr.size();    // Very important, add the replacement substring size
                                // to pos to avoid infinite loops
    }

  cout << "Resulting string: "<<original<<endl;
  return 0;
}

If we run this code, the two occurrences of “sleep” will be replaced by “code”. But we find a interesting comment in the code: “to avoid infinite loops”, what we do is adding the size of the string “code” to the pos variable. This would be a special case when the substring to be replaced is contained inside the replacement string (or they both are the same), in other words, if we search “to” and we want to replace it by “ton” and we comment this line. It will do the replacement with no ending, and if we cout the string inside the loop we will se “tonnnnnn … with a growing number of n”.

We have now a good way to do search and replace, so let’s create a function to simplify the usage, but with an added value: we can give an offset value (so we can choose where to start searching in the original string, just giving pos a non-zero value), and a counter, so we can replace fromStr with toStr a number of times, so if our keyword appears ten times, we can choose to replace it five times.

Let’s do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>

using namespace std;

string replace(string source, string fromStr, string toStr, int offset=0, int times=0)
{
  int total = 0;
  string::size_type pos=offset;
  while ( ( (pos = source.find(fromStr, pos)) < string::npos) && ( (times==0) || (total++<times) ) )
    {
      source.replace(pos, fromStr.length(), toStr);
      pos+=toStr.size();
    }
  return source;
}

int main()
{
  string original = "Going to sleep. Everyone knows past 12 we must go to sleep. So if I sleep tonight, I don't have to sleep tomorrow morning";

  cout << "Original string: "<<original<<endl;

  cout << "Resulting string: "<<replace(original, "sleep", "code 20, 2)<<endl;

  return 0;
}

The output will be like this:

Original string: Going to sleep. Everyone knows past 12 we must go to sleep. So if I sleep tonight, I don’t have to sleep tomorrow morning
Resulting string: Going to sleep. Everyone knows past 12 we must go to code. So if I code tonight, I don’t have to sleep tomorrow morning.

So, we start searching substring “sleep” from character number 20, and then replace this substring twice. The replace function has initial values, so if we omit offset we will start from the beginning of the string, and if we omit the number of times, this will be zero, and it means all occurrences will be replaced.

To make it better, we can make use of Glib::ustring instead of string. Glib is a cross-platform utility library that implements its own version of string with UTF8 support. So if we use special characters like tildes or symbols we will have encoding problems. We can test it this way:

1
2
3
4
5
6
7
#include <string>

int main()
{
  cout << string("piñata").length() << endl;
  return 0;
}

Let’s see the output. We know “piñata” has six letters, but sometimes we will get seven because we are using a multibyte encoding (like UTF8 wich uses two bytes to encode “ñ”). There it goes Glib::ustring, this library (free, of course), behaves exactly like string (but with UTF-8 support. Let’s see:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <string>
#include <iostream>
#include <glibmm/ustring.h>

using namespace std;

int main()
{
  cout << Glib::ustring("piñata").length()<<endl;
  cout << string("piñata").length()<<endl;

  return 0;
}

To compile:

$ g++ -o wordlength wordlength.cpp `pkg-config –libs –cflags glibmm-2.4`

We will have to install the library glibmm (version 2.4 as October 2013)

In this example (if the source file is saved with utf-8 encoding), it will give us the right value

And of course, the replace function can be compatible with Glib::ustring, just replacing string with Glib::ustring:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <glibmm/ustring.h>

using namespace std;

Glib::ustring replace(Glib::ustring source, Glib::ustring fromStr, Glib::ustring toStr, int offset=0, int times=0)
{
  int total = 0;
  Glib::ustring::size_type pos=offset;
  while ( ( (pos = source.find(fromStr, pos)) < Glib::ustring::npos) && ( (times==0) || (total++<times) ) )
    {
      source.replace(pos, fromStr.length(), toStr);
      pos+=toStr.size();
    }
  return source;
}

int main()
{
  Glib::ustring original = "Going to sleep. Everyone knows past 12 we must go to sleep. So if I sleep tonight, I don't have to sleep tomorrow morning.";

  cout << "Original string: "<<original.raw()<<endl;

  cout << "Resulting string: "<<replace(original, "sleep", "code").raw()<<endl;

  return 0;
}

Notice that I’ve used the method raw() to display the string with cout, this is because we have to pass just bytes to cout and not characters (in this case, multibyte characters).

Photo: Jon-Eric Melsæter (Flickr) CC-by

Top