Get ASCII value for character when higher than 127

S

ssetz

Hello,

For work, I need to write a password filter. The problem is that my C+
+ experience is only some practice in school, 10 years ago. I now
develop in C# which is completely different to me.

But, the password filter needs to be built, so I'm doing my best.
First of all, I am creating an xml string that contains both username
and password, and then I want to write the ascii values for all
characters to a textfile. By using the ascii values I am sure I can
store special characters, also in a textfile.

I got it working, but only when the password only contains characters
that have an ASCII value lower than 127. But, in windows it is
possible to change a password also to something that contains special
characters, like é, ë, or €.so I also need to be able to get these
characters in my filter.

Below is the code that works for characters with ASCII values lower
than 127. Can anyone tell me what I need to do to get this working for
all characters?

I've been searching and puzzling for two days now and haven't gotten
any closer to how to solve this.

Any help will be appreciated.

Thanks in advance,
Sandra


==================================================================

#include <windows.h>
#include <ntsecapi.h>
#include <time.h>
#include <fstream>
#include <iostream>
#include "PwdHookNew.h"
#include <sstream>
#include <string>

using namespace std;

#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif

string GetASCIIString(string oristring)
{
unsigned char ch;

int i, j, k;
string numstrings;

ostringstream oss;

for(i=0;i<oristring.size();i++)
{
ch=oristring;
k = int(ch);

if (k<10)
{
oss << "000" << k << "-";
}
else if (k<100)
{
oss << "00" << k << "-";
}
else if(k<1000)
{
oss << "0" << k << "-";
}
else
{
oss << k << "-";
}
}
numstrings=oss.str();
oss.clear();

return numstrings;
}

NTSTATUS
NTAPI
PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING Password
)
{
const char* timeStringFormat = "%Y-%m-%d_%H-%M-%S";
const int timeStringLength = 20;
char timeString[timeStringLength];

// get current date and time
time_t t = time(0);
tm *curTime = localtime(&t);

strftime(timeString, timeStringLength, timeStringFormat,
curTime);

char path[80];
strcpy (path,"C:\\pwds\\");
strcat (path,timeString);
strcat (path,".txt");

char *usernameStr, *passwordStr;

usernameStr = (char*)calloc(1, (UserName->Length/2)+1);
passwordStr = (char*)calloc(1, (Password->Length/2)+1);


wcstombs(usernameStr, UserName->Buffer, (UserName->Length/2));
wcstombs(passwordStr, Password->Buffer, (Password->Length/2));

char xmlmsg[150];
strcpy (xmlmsg,"<userpwd><username>");
strcat (xmlmsg,usernameStr);
strcat (xmlmsg,"</username><password>");
strcat (xmlmsg,passwordStr);
strcat (xmlmsg,"</password></userpwd>");

string xmlASCII = GetASCIIString(xmlmsg);

ofstream outPwd(path, ios::app);

if (!outPwd)
{
ofstream outPwd(path, ios::eek:ut );
}

outPwd << xmlASCII ;
outPwd.close();

return STATUS_SUCCESS;
}
 
P

Pete Becker

I got it working, but only when the password only contains characters
that have an ASCII value lower than 127. But, in windows it is
possible to change a password also to something that contains special
characters, like é, ë, or €.so I also need to be able to get these
characters in my filter.

ASCII values are never greater than 127. But since you're deep in
Windows land, you're dealing with some encoding that's not ASCII. In any
event, you should ask on a Microsoft newsgroup.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
O

Obnoxious User

(e-mail address removed) skrev:
Hello,

For work, I need to write a password filter. The problem is that my C+
+ experience is only some practice in school, 10 years ago. I now
develop in C# which is completely different to me.

But, the password filter needs to be built, so I'm doing my best.
First of all, I am creating an xml string that contains both username
and password, and then I want to write the ascii values for all
characters to a textfile. By using the ascii values I am sure I can
store special characters, also in a textfile.

I got it working, but only when the password only contains characters
that have an ASCII value lower than 127. But, in windows it is
possible to change a password also to something that contains special
characters, like é, ë, or €.so I also need to be able to get these
characters in my filter.

Below is the code that works for characters with ASCII values lower
than 127. Can anyone tell me what I need to do to get this working for
all characters?

I've been searching and puzzling for two days now and haven't gotten
any closer to how to solve this.

Any help will be appreciated.

As Pete said, ASCII is defined within the range 0-127, everything above
is something else. Either you proceed with partial/complete unicode
support, or You need to decide which charset(s) you wish to support.

http://en.wikipedia.org/wiki/Charset
http://en.wikipedia.org/wiki/Unicode
http://en.wikipedia.org/wiki/ISO/IEC_8859-1

That's something you need to consider first.

If you only need the characters 128-255, then I would recommend Latin-1,
as it's a subset of unicode, and a superset of ascii, unless you have
special needs provided by some other charset.
 
M

Marcus Kwok

For work, I need to write a password filter. The problem is that my C+
+ experience is only some practice in school, 10 years ago. I now
develop in C# which is completely different to me.

But, the password filter needs to be built, so I'm doing my best.
First of all, I am creating an xml string that contains both username
and password, and then I want to write the ascii values for all
characters to a textfile. By using the ascii values I am sure I can
store special characters, also in a textfile.

I got it working, but only when the password only contains characters
that have an ASCII value lower than 127. But, in windows it is
possible to change a password also to something that contains special
characters, like é, ë, or ¤.so I also need to be able to get these
characters in my filter.

I think Pete Becker is right about needing to consult a Windows group
for this question. However, something jumped out at me in the below
code:
string GetASCIIString(string oristring)
{
unsigned char ch;

int i, j, k;
string numstrings;

ostringstream oss;

for(i=0;i<oristring.size();i++)
{
ch=oristring;
k = int(ch);

if (k<10)
{
oss << "000" << k << "-";
}
else if (k<100)
{
oss << "00" << k << "-";
}
else if(k<1000)
{
oss << "0" << k << "-";
}
else
{
oss << k << "-";
}


You can probably replace the if/else chain here with:

oss << setw(4) << setfill('0') << k << '-';

This will require #include'ing <iomanip>. I left off the namespace
qualifiers (the std:: at the front of std::setw and std::setfill) since
from the rest of your code it looks like you are already doing a "using
namespace std".
 
N

niklasb

Hello,

For work, I need to write a password filter. The problem is that my C+
+ experience is only some practice in school, 10 years ago. I now
develop in C# which is completely different to me.

But, the password filter needs to be built, so I'm doing my best.
First of all, I am creating an xml string that contains both username
and password, and then I want to write the ascii values for all
characters to a textfile. By using the ascii values I am sure I can
store special characters, also in a textfile.

I got it working, but only when the password only contains characters
that have an ASCII value lower than 127.

Your code converts from a wide-character string (wchar_t*) to a
character
string (char*). Depending on the character set of the character
string,
some characters may be lost in this conversion. (Your attempt to
correct
this by encoding them as numbers in GetASCIIString doesn't work
because
the lossy conversion from wchar_t* to char* has already occurred by
this
point.)

I would suggest using wide-character strings internally in your code
and only convert to char* on final output, if at all. When you do the
conversion either use an 8-bit encoding that can handle the full
character repertoir (i.e., UTF-8) or use an escaping scheme (XML
defines
one so no need to invent your own).

Better yet, since you're output is an XML file use a library to handle
the XML output. A good XML library will handle the character
conversion
for you, as well as any escaping (including escaping of characters
reserved by XML such as < and &, which you neglected to do), and
ensure
that the resulting XML file is well-formed.

Since you're on Windows, XmlLite would be a good choice, but many
other
options are available.
 
J

James Kanze

(e-mail address removed) wrote:
ASCII values are never greater than 127. But since you're deep in
Windows land, you're dealing with some encoding that's not ASCII. In any
event, you should ask on a Microsoft newsgroup.

I was about to say the same thing about ASCII. But there is one
point which might be relevant here: regardless of the encoding,
characters which are not in the basic character set may have
negative encodings when stored in a char. Thus, for example, in
ISO 8859-1, 'é' has the code 233 (0xE9), but if I store it in a
char on my machine (a Sun Sparc under Solaris, so no Microsoft
in view), the value I get is -23. Casting it to an unsigned
char, or and'ing it with 0xFF, is necessary to get the correct
value. (I don't know if this problem is related to his original
code, but it would seem related to the subject line he gave.)
 
P

Pete Becker

James said:
(I don't know if this problem is related to his original
code, but it would seem related to the subject line he gave.)

Could be. On the other hand, the code was clearly Windows, and Windows
divides encodings into two categories: wide and ascii, represented by
wchar_t and char, respectively. One nasty example (for other reasons) is
that many Windows entry points have names that are defined as macros in
the headers, and expand to different names depending on whether _UNICODE
is defined; when it's not, the actual name is the original macro name
with 'A' appended (for ASCII), and when it is defined, the actual name
is the original macro name with 'W' appended (for wide). The 'A'
versions take strings as char*s; the 'W' versions take wchar_t*s.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top