Форум программистов, компьютерный форум CyberForum.ru

Перевести строку в 16-й формат - C++

Восстановить пароль Регистрация
 
 
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
22.11.2015, 20:33     Перевести строку в 16-й формат #1
Нужно перевести строку(string) в 16-й формат, как сделать? Знаю про std:hex, но он работает только с char и записать получаемое число в другую переменную нельзя.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
25.11.2015, 17:42  [ТС]     Перевести строку в 16-й формат #21
Все работает, спасибо. А можно вопрос. Сколько Вы лет изучали язык, чтобы сходу все это сделать ?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
25.11.2015, 21:04     Перевести строку в 16-й формат #22
Не знаю даже. Я его не изучал так, как в школе или в ВУЗе что-то изучают. Конкретно про rdbuf() была тема здесь на форуме; о том, что string может содержать что угодно, говорится в документации.
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
26.11.2015, 18:16  [ТС]     Перевести строку в 16-й формат #23
Вроде все сделал как надо, но условие наличия вируса срабатывает при любых условиях, даже если сигнатуры нет в exe. В чем причина ошибки ?
C++
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#pragma once
 
#ifndef SCAN_H_INCLUDED
#define SCAN_H_INCLUDED
 
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
 
using namespace std;
 
void scan(char* pathToFile)
{
    string bytes;
    ostringstream oss;
    ifstream base("C:\\Base.bas");
    ifstream readFile(pathToFile, ifstream::binary);
    bool flag = false;
    char choise;
 
    oss << readFile.rdbuf();
 
    string data = oss.str(); // содержимое файла записываем в data
 
    readFile.close(); //закрываем файл
 
    int p;
    while (!base.eof())
    {
        getline(base, bytes);
        if ((p = data.find(bytes)) != string::npos)//ищем нужную последовательность в последовательности файла
        {
            flag = true;
            break;
        }
    }
    if (base.eof() && flag == true)//Если файл закончился и флаг принял значение 1, то вирус есть
    {
        cout << "est virus!" << endl;//Вывод сообщения об опасности
        cout << "Enter what you want to do(d - delete, s - skip): ";//Приглашение на ввод буквы соответствующему ей выбору
        cin >> choise;//Ввод одной буквы
        for (int i = 0; i < 1; i++)//Предполагает только один ввод
        {
            switch (choise)
            {
            case 'd'://Удаление файла
            {
                if (remove(pathToFile) != 0)//Если файл не удалился
                    cerr << "File isn't deleted!" << endl;//Сообщение об ошибке, что файл не удален
                else cout << "File is deleted!" << endl;//Если удален, то вывести, что файл удален
                break;
            }
 
            case 's'://Пропуск файла
            {
                cout << "File is skiped!" << endl;
                continue;//Продолжить работу
                break;
            }
            default:
                cout << "Enter 'd' or 's'" << endl;
                break;
            }
        }
    }
    
}
 
#endif
В файле - \x4d\x5a (Данной последовательности нет в exe).
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
26.11.2015, 19:40     Перевести строку в 16-й формат #24
Если сигнатуры записаны текстом, то при чтении нужно конвертировать. \x4d\x5a - это формат для программы C++, а в файле должно быть 4d5a. Примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
    while (getline(base, bytes))
    {
        string b;
        for (int i = 0; i < bytes.size(); i += 2)
            b += static_cast<char>(stoi(bytes.substr(i, 2), nullptr, 16));
        if ((p = data.find(b)) != string::npos)//ищем нужную последовательность в последовательности файла
        {
            flag = true;
            break;
        }
    }
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
26.11.2015, 20:03  [ТС]     Перевести строку в 16-й формат #25
В stoi(bytes.substr(i,2) указана длина - 2 . Можно ли применять string::npos вместо данного параметра?
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
26.11.2015, 20:10     Перевести строку в 16-й формат #26
Нет. У тебя же байт в шестнадцатеричном текстовом виде - это 2 символа. Поэтому 2.

Добавлено через 1 минуту
Думаю, что настоящие антивирусы не хранят сигнатуры текстом, они там бинарные сразу, поэтому конвертация не требуется.
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
26.11.2015, 20:14  [ТС]     Перевести строку в 16-й формат #27
Все антивирусные базы закрыты, только сами разработчики знают, какого они вида. В 16 виде их легче хранить(меньше памяти исходный файл будет занимать) и проверка в разы быстрее из-за размера исходной строки.
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
26.11.2015, 20:16     Перевести строку в 16-й формат #28
В бинарном меньше будет, а у тебя в текстовом - один реальный байт - это 2 байта символов текста.

Добавлено через 54 секунды

Не по теме:

Nik-, ты решил Касперского разорить или что?

Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
26.11.2015, 20:18  [ТС]     Перевести строку в 16-й формат #29
Получается, что записав в базу, допустим, 01001, то это сработает ? Если это вирусная сигнатура, и она присутствует в файле произойдет детектирование ?
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
26.11.2015, 20:24     Перевести строку в 16-й формат #30
Ну я же показал, как надо. Пишешь сигнатуру в шестандцатеричном виде. Каждую в своей строке. С лидирующими нулями при необходимости, т. е. не F, а 0F и т. п.
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
28.11.2015, 21:44  [ТС]     Перевести строку в 16-й формат #31
Мне дали задание "лечить" зараженные файлы путем удаления сигнатуры вируса из файла. С exe, который я создаю через блокнот все выходит, но с другими уже нет. Есть другие варианты делать это, не такие, как мой? Сделал так
C++
1
2
3
4
5
ofstream review(pathToFile, ios_base::trunc);
                data.erase(p, signature.size());//Удаляем сигнатуру вируса из буффера, содержащего данные файла
                review << data;//Записываем измененные данные файл(файл безопасен)
                cout << "File is reviewed!" << endl;
                review.close();
Добавлено через 1 минуту
Определяется наличия вируса так.
C++
1
2
3
4
5
6
7
8
9
10
while (getline(base, bytes))//Пока идет запись текста из базы в переменную
    {
        for (int i = 0; i < bytes.size(); i += 2)
            signature += static_cast<char>(stoi(bytes.substr(i, 2), nullptr, 16));//Записываем в переменную сигнатуру
        if ((p = data.find(signature)) != string::npos)//ищем нужную последовательность в последовательности файла
        {
            flag = true;//Флаг - 1. Вирус обнаружен
            break;//Останавливаем цикл
        }
    }
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
28.11.2015, 22:15     Перевести строку в 16-й формат #32
В двоичном режиме открывай review.
Так что происходит-то? Не удаляется, не записывается?
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
28.11.2015, 22:47  [ТС]     Перевести строку в 16-й формат #33
Я сам не могу понять, скорее всего не удаляется, т.к после удаление содержания ехе его иконка изменяется на обычную иконку исполняемого файла, но такого не происходит.
WhiteP
605 / 203 / 23
Регистрация: 20.11.2012
Сообщений: 419
29.11.2015, 07:02     Перевести строку в 16-й формат #34
Цитата Сообщение от Nik- Посмотреть сообщение
Мне дали задание "лечить" зараженные файлы путем удаления сигнатуры вируса из файла.
Задание университетское, судя по всему?
Для низкоуровневой работы с потоком байт C++ лишнее, имхо. Лучше тут простые Сишные возможности использовать, вместо того, чтобы городить этот высокоуровневый код). Удобно через mapped файлы работать. Для поиска подстроки в строке есть много хороших быстрых алгоритмов.
Так что если не сказано в задании работать именно с высокоуровневыми абстракциями C++, то стоит обратить внимание на подмножество Си в С++.
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
29.11.2015, 08:53     Перевести строку в 16-й формат #35
Да пусть хоть это отладит.
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
29.11.2015, 10:15  [ТС]     Перевести строку в 16-й формат #36
Алгоритмы поиска подстроки знаю, но удобнее, все же, использовать find(), имхо. С отображением файлов в память не работал, возможно, если все ошибки устраню, то воспользуюсь mapping' ом. Но вопрос остается вопросом. Почему не удаляется содержимое exe. (Мучаю exe, установленные на компьютер).
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
29.11.2015, 10:57     Перевести строку в 16-й формат #37
Программу покажи.
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
29.11.2015, 11:05  [ТС]     Перевести строку в 16-й формат #38
Весь заголовочный файл сканирования. Скорее всего не работает удаление. 71 строка.
C++
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#pragma once
 
#ifndef SCAN_H_INCLUDED
#define SCAN_H_INCLUDED
 
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
 
using namespace std;
 
void scan(char* pathToFile)
{
    string bytes;//Перемнная для содержания сигнатуры
    string signature;//Перемнная для содержания сигнатуры после конвертации в 16 вид
    ostringstream oss;//Поток для записи из файла в переменну.
    ifstream base("C:\\Base.bas");//Поток чтения из файла
    if (!base.is_open())//Проверка на открытие файла
        cerr << "Base can't be opened!" << endl;
    ifstream suspectFile(pathToFile, ifstream::binary);//Потое открытия проверяемого файла
    if (!suspectFile.is_open())//Проверка на открытие файла
        cerr << "Can't open file!" << endl;
 
    bool flag = false;//Флаг, определяющий наличие вируса. 1 - есть, 0 - нет.
    char choise;//Выбор
 
    oss << suspectFile.rdbuf();//Записываем в поточную переемнную текст из файла, открытого в двоичном режиме
    string data = oss.str(); // содержимое файла записываем в data
 
    suspectFile.close(); //закрываем файл
 
    int p;
    
    while (getline(base, bytes))//Пока идет запись текста из базы в переменную
    {
        for (int i = 0; i < bytes.size(); i += 2)
            signature += static_cast<char>(stoi(bytes.substr(i, 2), nullptr, 16));//Записываем в переменную сигнатуру
        if ((p = data.find(signature)) != string::npos)//ищем нужную последовательность в последовательности файла
        {
            flag = true;//Флаг - 1. Вирус обнаружен
            break;//Останавливаем цикл
        }
    }
    
    if (flag == true)//Если файл закончился и флаг не принял значение 1, то вирус есть
    {
        cout << "Est virus!" << endl;//Вывод сообщения об опасности
        cout << "Enter what you want to do(d - delete, s - skip, r - review): ";//Приглашение на ввод буквы соответствующему ей выбору
        cin >> choise;//Ввод одной буквы
 
        for (int i = 0; i < 1; i++)//Предпологает только один ввод
        {
            switch (choise)
            {
            case 'd'://Удаление файла
            {
                if (remove(pathToFile) != 0)//Если файл не удалился
                    cerr << "File isn't deleted!" << endl;//Сообщение об ошибке, что файл не удален
                else cout << "File is deleted!" << endl;//Если удален, то вывести, что файл удален
                break;
            }
 
            case 's'://Пропуск файла
            {
                cout << "File is skiped!" << endl;
                continue;//Продолжить работу
                break;
            }
 
            case 'r'://лечить
            {
                ofstream review(pathToFile, ios::binary ,ios_base::trunc);
                data.erase(p, signature.size());//Удаляем сигнатуру вируса из буффера, содержащего данные файла
                review << data;//Записываем измененные данные файл(файл безопасен)
                cout << "File is reviewed!" << endl;
                review.close();
            }
            default:
                cout << "Enter 'd', 's' or 'r'" << endl;
                break;
            }
        }
    }
    else cout << "Virusov net!" << endl;
    base.close();
}
 
#endif
nmcf
4311 / 3732 / 1258
Регистрация: 14.04.2014
Сообщений: 14,624
29.11.2015, 19:02     Перевести строку в 16-й формат #39
C++
1
std::ofstream review(pathToFile, std::ofstream::binary | std::ofstream::trunc);
В остальном работает. Фрагмент удаляется. Файл становится короче.
Что конкретно не устраивает?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.11.2015, 20:10     Перевести строку в 16-й формат
Еще ссылки по теме:

Перевести длинную бинарную строку в строку с десятичными цифрами C++
Перевести 1 строку с С#на С++ C++
Как перевести строку в BSTR* C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
29.11.2015, 20:10  [ТС]     Перевести строку в 16-й формат #40
Это скорее всего происходило из-за расположения. После перемещения файла на диск D все пошло как надо. Спасибо. Как было сказано выше, можно использовать проецирование файла в память, стоит ли это делать?
Yandex
Объявления
29.11.2015, 20:10     Перевести строку в 16-й формат
Ответ Создать тему
Опции темы

Текущее время: 15:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru