Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5c08ace

Browse files
Add Lib Hash
1 parent de71cfc commit 5c08ace

File tree

7 files changed

+175
-86
lines changed

7 files changed

+175
-86
lines changed

‎SH12-Notebook.pdf

14 KB
Binary file not shown.

‎pdf/README.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ Em [notebook.tex](notebook.tex) você pode personalizar configuraçãos do Latex
5656

5757
Edite o arquivo [generate_latex.cpp](generate_latex.cpp) para alterar opções como:
5858

59+
- **Hash**: altere ```bool USE_HASH = true;``` para adicionar ou omitir o hash dos arquivos. Veja mais detalhes na seção Hash.
60+
5961
- **IGNORED_LINES**: ignora **linhas inteiras** com determinados valores de substring (ex: ```#include <bits/stdc++.h>"```, ```"using namespace std;```, ```#define pii pair<int, int>```).Cuidado para não remover algo que você não gostaria que fosse removido.
6062

6163
- **IGNORED_SUBSTRINGS**: ignora substrings específicas no código (ex: ```std::```).
@@ -87,9 +89,43 @@ LATEX_DESC_END*/
8789
<img src="images/latex_desc_img.jpg" width="45%"/>
8890
</p>
8991

90-
### ~~Hash~~
92+
### 💿 Hash
93+
94+
Gera um código hash hexadecimal de cada linha do código (3 caracteres por padrão).
95+
96+
Pode ser usado para conferir se o código foi copiado igual ao que está lib. O hash **ignora comentários, espaçamento e identação**.
97+
Além disso em cada linha que possui um ```}``` terá o hash não somente dessa linha, mas **o hash de todo o contexto** referente, desde a linha do ```{``` que abriu esse contexto. Isto é, de tudo que está entre ```{...}```. Assim você pode conferir funções inteiras mais rapidamente. *Útil para códigos complexos e longos*.
98+
99+
Para conferir o hash na hora da prova, copie este código (já adicionado na lib por padrão se USE_HASH) e em seguida execute
100+
101+
```shell
102+
g++ hash.cpp -o hash
103+
hash < codigo.cpp
104+
```
105+
106+
```cpp
107+
string getHash(string s, int dig=3){
108+
ofstream ip("temp.cpp"); ip << s; ip.close();
109+
system("g++ -E -P -dD -fpreprocessed .\\temp.cpp | tr -d '[:space:]' | md5sum > hsh.temp");
110+
ifstream f("hsh.temp"); f >> s; f.close();
111+
return s.substr(0, dig);
112+
}
113+
114+
int main(){
115+
string l, t;
116+
vector<string> st(100);
117+
while(getline(cin, l)){
118+
t = l;
119+
for(auto c : l)
120+
if(c == '{') st.push_back(""); else
121+
if(c == '}') t = st.back() + l, st.pop_back();
122+
cout << getHash(t) + " " + l + "\n";
123+
st.back() += t + "\n";
124+
}
125+
}
126+
```
91127
92-
Não consegui terminar os códigos para adicionar o hash das linhas de código na lib. Mas sinta-se a vontade para contribuir.
128+
<small> * Inspirado e compatível com o Hash utilizado na Lib [brunomaletta/Biblioteca](https://github.com/brunomaletta/Biblioteca/) </small>
93129
94130
<hr>
95131

‎pdf/contents.txt

370 Bytes
Binary file not shown.

‎pdf/generate_latex.cpp

Lines changed: 68 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#include <bits/stdc++.h>
22
#include <regex>
3+
#define t_section tuple<string, string, bool>
34
using namespace std;
45

6+
const bool USE_HASH = true;
7+
const int HASH_LEN = 3;
58

69
const vector<string> IGNORED_LINES = {
710
"#include <bits/stdc++.h>",
@@ -38,9 +41,7 @@ const string BLOCK_DESC_END = "BLOCK_DESC_END";
3841

3942
const bool USE_MARKDOWN_IN_DESC = true;
4043

41-
// hash incompleto - não usar
42-
const bool USE_HASH = false;
43-
const int HASH_LEN = 3;
44+
const bool IGNORE_EMPTY_LINES = false;
4445

4546
map<char32_t, char> char_changes = {
4647
{0x00E7, 'c'}/*ç*/, {0x00E3, 'a'}/*ã*/, {0x00E1, 'a'}/*á*/,
@@ -56,22 +57,29 @@ map<char32_t, char> char_changes = {
5657
{U'\x2019', '\''}, {U'\x3b1', 'a'}, {U'\x2013', '-'},
5758
};
5859

59-
//// Code Start Here ////
60+
//// Code Start Here ///
61+
#include "hash/md5hsh.cpp" // Include another hash function if you want to use other
62+
const string HASH_CODE = "./hash/md5hsh.cpp"; // Path to the hash code that will be used (To put on lib)
63+
string _get_code_hash_(string code){
64+
return getCodeHash(code, HASH_LEN);
65+
}
66+
6067
const string COMMENT_BLOCK_DESC_BGN = R"(/\*+\s*)" + BLOCK_DESC_BGN;
6168
const string COMMENT_BLOCK_DESC_END = BLOCK_DESC_END + R"(\s*\*+/)";
6269

6370
void remove_whitespace(string& s){
64-
while(!s.empty() && (s.back() == '\n' || s.back() == '\t' || s.back() == '\r' || s.back() == ''))
71+
while(!s.empty() && isspace(s.back()))
6572
s.pop_back();
6673
}
6774

6875
void remove_front_whitespace(string& s){
6976
int skp = 0;
70-
while(skp < s.size() && (s.front() == '\n' || s.front() == '\t' || s.front() == '\r' || s.front() == ''))
77+
while(skp < s.size() && isspace(s[skp]))
7178
skp++;
7279
s.erase(0, skp);
7380
}
7481

82+
7583
void remove_ignored_substrings(string& s) {
7684
size_t pos = 0;
7785
for(const auto& substr : IGNORED_SUBSTRINGS)
@@ -153,14 +161,16 @@ bool is_comment(string line) {
153161
if (line.size() >= 2 and line.substr(0, 2) == "/*") comment = true;
154162
return comment;
155163
}
156-
164+
165+
const string BLOCK_DESC_MARK = "BLOCK_DESC_MARK\n";
157166
bool convert_files(const string& input_path, const string& output_path, string& description, bool PRINT_HASH = false){
158167
ifstream in(input_path, ios::binary);
159168
if(!in){ cerr << "Error opening input file: " << input_path << endl; return false; }
160169
string content((istreambuf_iterator<char>(in)), istreambuf_iterator<char>());
161170
in.close();
162171

163172
bool can_begin = false, isInDesc = false, ignore_interval = false, isInBlckDesc = false;
173+
vector<string> block_descs, block_desc_desc;
164174
string processed_content, line, block_desc="";
165175
description = "";
166176
size_t pos = 0;
@@ -219,8 +229,14 @@ bool convert_files(const string& input_path, const string& output_path, string&
219229
remove_front_whitespace(block_desc);
220230
remove_whitespace(processed_content);
221231
block_desc = block_desc.empty() ? "\n" : "\n@\\blockdesc{" + block_desc + "}@\n";
222-
if(BLOCK_DESC) processed_content += block_desc;
223-
else description += block_desc + "\n";
232+
if(isInDesc){
233+
block_desc_desc.emplace_back(block_desc),
234+
description += BLOCK_DESC_MARK;
235+
}
236+
else {
237+
block_descs.emplace_back(block_desc);
238+
processed_content += "\n" + BLOCK_DESC_MARK;
239+
}
224240
can_begin = false;
225241
isInBlckDesc = false;
226242
block_desc.clear();
@@ -238,6 +254,7 @@ bool convert_files(const string& input_path, const string& output_path, string&
238254

239255
if(ADD_DESC && isInDesc && !ignore){ description += line + "\n"; continue; }
240256
if(line.find(DESC_END) != string::npos) isInDesc = false; //if(line.find(MY_DESC_END) != string::npos) isInDesc = false;
257+
if(IGNORE_EMPTY_LINES && blank_line) continue;
241258

242259
if(!ignore && !blank_line) can_begin = true;
243260
if(!can_begin || ignore) continue;
@@ -254,7 +271,21 @@ bool convert_files(const string& input_path, const string& output_path, string&
254271
remove_ignored_substrings(description);
255272
description = convert_description(description);
256273

257-
// if(PRINT_HASH) processed_content = get_file_hash(processed_content);
274+
if(PRINT_HASH) processed_content = _get_code_hash_(processed_content);
275+
276+
for(auto blck : block_descs){
277+
auto bgn = processed_content.find(BLOCK_DESC_MARK);
278+
int sz = BLOCK_DESC_MARK.size();
279+
while(bgn > 0 && processed_content[bgn] != '\n') bgn--, sz++;
280+
processed_content.replace(bgn, sz, blck);
281+
}
282+
283+
for(auto blck : block_desc_desc){
284+
auto bgn = description.find(BLOCK_DESC_MARK);
285+
int sz = BLOCK_DESC_MARK.size();
286+
while(bgn > 0 && description[bgn] != '\n') bgn--, sz++;
287+
description.replace(bgn, sz, blck);
288+
}
258289

259290
// Ensure output directory exists
260291
filesystem::path out_path(output_path);
@@ -281,19 +312,19 @@ string get_style(const string& filename) {
281312
return "txt";
282313
}
283314

284-
string get_tex(const vector<pair<string, vector<pair<string, string>>>>& sections, bool PRINT_HASH=false) {
315+
string get_tex(const vector<pair<string, vector<t_section>>>& sections) {
285316
string tex, description;
286317
for(auto& [section_name, subsections] : sections) if(!subsections.empty()){
287318
tex += "\\section{" + section_name + "}\n";
288319

289-
for(auto [filename, subsection_name] : subsections){
320+
for(auto [filename, subsection_name, file_hash] : subsections){
290321
cout << get_style(filename) + "\t| " << filename << endl;
291322
if(get_style(filename) == "tex"){ tex += "\\input{" + filename + "}\n"; continue; }
292323

293324
string newpath = "./temp/" + filename, full_path = filename;;
294-
newpath = regex_replace(newpath, regex(R"(\.\./)"), ""); // remove qualquer ../ de newpath
325+
newpath = regex_replace(newpath, regex(R"(\.\./|\./)"), ""); // remove qualquer ../ ou ./ de newpath
295326

296-
if(convert_files(full_path, newpath, description, PRINT_HASH))
327+
if(convert_files(full_path, newpath, description, USE_HASH&&file_hash&&get_style(filename)=="cpp"))
297328
full_path = newpath;
298329

299330
tex += "\\vspace{-2pt}\n";
@@ -315,8 +346,8 @@ string get_tex(const vector<pair<string, vector<pair<string, string>>>>& section
315346
return tex;
316347
}
317348

318-
vector<pair<string, vector<pair<string, string>>>> get_sections() {
319-
vector<pair<string, vector<pair<string, string>>>> sections;
349+
vector<pair<string, vector<t_section>>> get_sections() {
350+
vector<pair<string, vector<t_section>>> sections;
320351

321352
ifstream f("contents.txt", ios::binary); // For UTF-16 handling on Windows
322353

@@ -339,7 +370,7 @@ vector<pair<string, vector<pair<string, string>>>> get_sections() {
339370
if(line.empty()) continue;
340371
if(line.find('#') < line.size()) continue;
341372

342-
if(line[0] == '[') sections.emplace_back(line.substr(1, line.size() - 2), vector<pair<string, string>>());
373+
if(line[0] == '[') sections.emplace_back(line.substr(1, line.size() - 2), vector<t_section>());
343374
else {
344375
size_t div_pos = line.find(div_char);
345376
if (div_pos >= line.size()) {
@@ -348,18 +379,21 @@ vector<pair<string, vector<pair<string, string>>>> get_sections() {
348379
continue;
349380
}
350381

382+
bool file_hash = true;
383+
if(line.find('@') < line.size()) file_hash = false, line[line.find('@')] = ' ';
384+
351385
string filename = line.substr(0, div_pos);
352-
while(!filename.empty() && (filename.back() == '' || filename.back() == '\t')) filename.pop_back();
386+
while(!filename.empty() && isspace(filename.back())) filename.pop_back();
353387
string subsection_name = line.substr(div_pos + 1);
354-
while(!subsection_name.empty() && (subsection_name.back() == '' || subsection_name.back() == '\t')) subsection_name.pop_back();
355-
while(!subsection_name.empty() && (subsection_name.front() == '' || subsection_name.front() == '\t')) subsection_name.erase(0, 1);
388+
remove_whitespace(subsection_name);
389+
remove_front_whitespace(subsection_name);
356390

357391
if(sections.empty()) {
358392
cerr << "Subsection given without section {" << line << "} " << line.size() << endl;
359393
continue;
360394
}
361395

362-
sections.back().second.emplace_back(filename, subsection_name);
396+
sections.back().second.push_back(t_section({filename, subsection_name, file_hash}));
363397
}
364398
}
365399

@@ -369,7 +403,19 @@ vector<pair<string, vector<pair<string, string>>>> get_sections() {
369403

370404
int main(){
371405
auto sections = get_sections();
372-
string tex = get_tex(sections, USE_HASH);
406+
407+
if(USE_HASH)
408+
{
409+
bool added_hash = false;
410+
for(auto& [section_name, subsections] : sections)
411+
if(section_name == "Extra")
412+
subsections.push_back(t_section({HASH_CODE, "Hash Function", true})),
413+
added_hash = true;
414+
if(!added_hash)
415+
sections.emplace_back("Extra", vector<t_section>({t_section({HASH_CODE, "Hash Function", true})}));
416+
}
417+
418+
string tex = get_tex(sections);
373419

374420
ofstream out("contents.tex");
375421
if(out.is_open()) out << tex;
@@ -380,65 +426,3 @@ int main(){
380426

381427
return 0;
382428
}
383-
384-
385-
386-
/*
387-
// #include <openssl/evp.h>
388-
// compute MD5 hash of a string
389-
string compute_md5_hash(const string& content, int size) {
390-
unsigned char digest[EVP_MAX_MD_SIZE];
391-
unsigned int digest_len;
392-
393-
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
394-
EVP_DigestInit_ex(mdctx, EVP_md5(), nullptr);
395-
EVP_DigestUpdate(mdctx, content.c_str(), content.size());
396-
EVP_DigestFinal_ex(mdctx, digest, &digest_len);
397-
EVP_MD_CTX_free(mdctx);
398-
399-
char mdString[33];
400-
for (unsigned int i = 0; i < 16; i++)
401-
sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]);
402-
403-
mdString[32] = '0円';
404-
return string(mdString).substr(0, size);
405-
}
406-
407-
string get_hash_arquivo(string &s, int size, int l = 0, int r = 1e9) {
408-
stringstream ss(s);
409-
string content = "", line;
410-
411-
// Lê apenas o intervalo especificado
412-
for (int i = 0; i <= r; i++){
413-
if (!getline(ss, line)) break;
414-
if (i >= l) content += line + "\n";
415-
}
416-
return compute_md5_hash(content, size);
417-
}
418-
419-
420-
// Process content and add hashes
421-
string get_file_hash(string& content){
422-
stringstream ss(content);
423-
string line, output = "";
424-
int depth = 0;
425-
stack<int> st;
426-
427-
for(int line_idx = 0; getline(ss, line); line_idx++){
428-
int start_line = line_idx;
429-
430-
for (char c : line)
431-
if (c == '{') depth++, st.push(line_idx); else
432-
if (c == '}') depth--, start_line = st.top(), st.pop();
433-
434-
string hash = "";
435-
if(!is_comment(line)) hash = get_hash_arquivo(content, HASH_LEN, start_line, line_idx);
436-
else if(depth != 0) hash = string(HASH_LEN + 1, ' ');
437-
438-
output += hash + " " + line + "\n";
439-
}
440-
441-
return output;
442-
}
443-
444-
*/

‎pdf/generate_pdf.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ mv notebook.tex _notebook.tex
1313
rm notebook.*
1414
mv _notebook.tex notebook.tex
1515
rm genLatex.exe
16+
mv hsh.temp ./temp/h
17+
mv temp.cpp ./temp/h
1618
rm ./temp -r
1719

1820
echo "

‎pdf/getContents.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
# Subsections within a section should follow the format:
1515
# (filename within code directory)(divisor character:{div_char})(subsection title)
1616
# div character:{div_char}
17+
18+
# If you add an '@' at the end of a file title, that file will not be hashed, even if use_hash is true.
1719
'''
1820
print(note)
1921

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /