1. Trang chủ
  2. » Giáo Dục - Đào Tạo

CÁC VẤN ĐỀ VỀ MÃ NGUỒN

83 354 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 83
Dung lượng 551 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Trình bày tổng thể 1 Môđun hóa chương trình  Chương trình của bạn nên được tách thành nhiều môđun, mỗi môđun thực hiện một công việc và càng độc lập với nhau càng tốt.. Điều này sẽ g

Trang 1

Giảng viên: TS Trần Đan Thư

CÁC VẤN ĐỀ VỀ MÃ NGUỒN

Trang 3

Các loại mã

Trang 5

i = 1 t1 = 4*i t2 = a[t1]

t3 = 4*i t4 = b[t3]

t5 = t2*t4 t6 = prod+t5 prod = t6

t7 = i+i

i = t7

if i ? N goto 4 retval prod

leave dotprod

Trang 6

Bytecode public Employee( String strName, int num)

Trang 7

7b bf jnp 0040008a 8b e9

mov ebp,ecx

64 b4 8b mov ah,8b

ea 64 b5 8b af 66 b4 jmp b466:af8bb564 8b 88 7b a7 8b ff mov ecx,[eax-00745885]

64 b4 8b mov ah,8b

02 7b be add bh,[ebx-42]

8b e6 mov esp,esi

64 b4 8b mov ah,8b ec

in al,dx 47

inc edi

bf 8b a0 64 b4 mov edi,b464a08b 8b 2d 62 b2 8b eb

Trang 8

Obfuscated code

nghĩa (đen tối hóa mã nguồn)

_( , _, ){ _/ <=1?_( , _+1, ):

!( _% )?_( , _+1,0): _% == _/

&&! ?(printf("%d\t", _/ ),_( , _+1,0)): _% >1&& _% < _/ ?_( ,1+

_, +!( _/ %( _% ))):

_< * ?_( , _+1, ):0;}main(){_(100,0,0);}

Trang 10

Trong sáng hóa mã nguồn

 Rất quan trọng trong quá trình lập trình với

nhiều lý do:

 80% chu kỳ sống của phần mềm là bảo trì

 Mã nguồn khó đọc chỉ có thể được bảo trì bởi

chính người viết ra nó

 Quy ước viết mã nguồn tăng khả năng dễ đọc

cho phần mềm, cho phép những lập trình viên khác nhanh chóng tiếp cận mã nguồn khi nó được tích hợp trên nhiều module khác nhau

 Phục vụ tốt công tác thanh tra mã nguồn

Trang 13

Trình bày tổng thể (1)

 Môđun hóa chương trình

 Chương trình của bạn nên được tách thành nhiều

môđun, mỗi môđun thực hiện một công việc và

càng độc lập với nhau càng tốt Điều này sẽ giúp bạn dễ bảo dưỡng chương trình hơn và khi đọc

chương trình, bạn không phải đọc nhiều, nhớ nhiều các đoạn lệnh nằm rải rác để hiểu được điều gì

đang được thực hiện

 Cách trình bày chương trình nên nhất quán

 Chương trình nên giữ được tính đơn giản và rõ ràng

trong hầu hết các tình huống

Trang 14

Trình bày tổng thể (2)

 Mã lệnh mà bạn viết phải thể hiện đúng cấu trúc

chương trình của bạn

 Chương trình của bạn nên thực hiện như một dòng

chảy từ trên xuống dưới, không nên có những thay đổi bất chợt Để có được điều này, bạn không nên sử dụng goto hay continue

Dòng lệnh

if (count == 0) printf("No data.\n");

nên được viết là

if (count == 0)

printf("No data.\n");

Trang 15

Khai báo biến và hàm (1)

 Biến nên được khai báo ở gần vị trí mà nó

bắt đầu được sử dụng, như vậy bạn sẽ

tránh được việc khai báo một loạt các biến

dư thừa ở đầu hàm hay chương trình.

 Mỗi biến nên khai báo trên một hàng nhằm

dễ chú thích về ý nghĩa của mỗi biến

int level = 0; //indentation level

int size = 0; //size of symbol table

int lines = 0; //lines read from input

Trang 16

Khai báo biến và hàm (2)

 Tên biến nên đặt ngắn gọn, nhưng đủ nghĩa Có thể

là các từ hoàn chỉnh hoặc là từ viết tắt Từ đầu tiên viết thường, các từ tiếp theo viết hoa chữ cái đầu

 Riêng với các biến điều khiển nên đặt đơn giản,

Trang 17

Khai báo biến và hàm (3)

 Các biến không nên được sử dụng lại với nhiều

nghĩa khác nhau trong cùng một hàm

 Các toán tử và toán hạng trong một biểu thức nên

được tách rời nhau nhằm làm biểu thức dễ đọc hơn

 Nên có khoảng trắng giữa từ khóa và dấu (, nhưng

không nên có khoảng trắng giữa tên hàm và dấu (

mass = volume * density;

Thay vì

mass=volume*density;

Trang 18

Khai báo biến và hàm (4)

 Tên các hằng số được viết hoa toàn bộ, các từ viết

cách nhau bằng dấu gạch dưới

 Các hằng số không nên viết trực tiếp vào chương

trình

int MIN_WIDTH = 4;

int MAX_WIDTH = 99 ;

popChange = (0.1758 - 0.1257) * population;

nên được viết là:

const double BIRTH_RATE = 0.1758;

const double DEATH_RATE = 0.1257;

Trang 19

Khai báo biến và hàm (5)

 Các kiểu dữ liệu do người dùng định nghĩa được viết

hoa toàn bộ hoặc viết hoa các ký tự đầu

 Khi khai báo con trỏ, dấu con trỏ nên được đặt liền

với tên, nhằm tránh trường hợp sau

BIGINT hay BigInt

char * p, q, r; //q, r không là con trỏ

Trong trường hợp này nên viết là

char *p, *q, *r;

Trang 20

Khai báo biến và hàm (6)

 Tên của một hàm (method) nên phản ánh công việc

hoặc giá trị trả về của nó Thường bắt đầu là động

từ, các từ tiếp theo thì viết hoa chữ cái đầu của mỗi từ

isEmpty() hoặc

getBackground() hoặc

run() hoặc

runFast()

Trang 21

Khai báo biến và hàm (7)

 Tên lớp (class) nên là danh từ, viết hoa chữ cái đầu

của mỗi từ Nên đặt tên lớp đơn giản nhưng phải đủ nghĩa, tránh dùng các ký hiệu và viết tắt, ngoại trừ

từ viết tắt đó là thông dụng (URL, HTML)

class Raster;

class ImageSprite;

Trang 22

Trình bày dòng lệnh (1)

 Một câu lệnh nên được đặt riêng trên một dòng,

điều này sẽ giúp bạn rất nhiều trong quá trình

Trang 23

Trình bày dòng lệnh (2)

 Nên sử dụng các dấu () khi muốn tránh các lỗi về

độ ưu tiên toán tử

Trang 24

Trình bày dòng lệnh (3)

 Nên dùng các dòng trắng để phân chia các hàm

trong một tập tin, các đoạn lệnh trong một hàm

như: đoạn nhập xuất dữ liệu, các đoạn tương ứng với các bước xử lý khác nhau

 Mỗi dòng lệnh không nên dài quá 80 ký tự, điều

này giúp việc đọc chương trình dễ dàng hơn khi

không phải thực hiện các thao tác cuộn ngang màn hình

Trang 25

} Hoặc

for (curr = *listp, trail = listp;

curr != NULL;

Trang 26

Thụt đầu dòng (1)

 Cặp dấu {} bao các khối lệnh, giúp người

đọc dễ hiểu cấu trúc chương trình hơn, và

nó được sử dụng trong hầu hết các ngôn ngữ lập trình

 Thụt đầu dòng (indent style) là vị trí đặt

các dấu {} và các lệnh bên trong khối lệnh

 Kích cỡ khoảng cách đặt { tùy thuộc vào

chuẩn mà chúng ta chọn (style)

 Nhiều chương trình rất sớm: tab

 Unix: tab=8 ký tự

 Macintosh: 4 ký tự

Trang 28

Thụt đầu dòng (3): K&R

 K&R style (Kernighan & Ritchie): được sử

dụng ở hầu hết các ngôn ngữ như: C, C++, C#

int main ( int argc, char *argv []) {

while ( x == y ) {

something () ; somethingelse () ;

if ( some_error )

do_correct () ; else

continue_as_usual () ; }

Trang 29

Thụt đầu dòng (4): 1TBS

 1TBS ("The One True Brace Style" ): Unix

kernel và Linux kernel sử dụng

if ( x < 0 ) {

printf ( "Negative" ) ; negative ( x ) ;

} else {

printf ( "Positive" ) ; positive ( x ) ;

}

Trang 30

Thụt đầu dòng (5): Allman

 Allman style (ANSI) :tương đương từ khóa

begin và end của Pascal, SQL Được sử

dụng bởi Microsoft Visual Studio 2005 and Apple's Xcode

while ( x == y ) {

something () ; somethingelse () ;

}

finalthing () ;

Trang 31

4

Trang 32

Thụt đầu dòng (6-2): BSD KNF

if ( data != NULL && res > 0 ) {

if ( JS_DefineProperty ( cx, o, "data" ,

STRING_TO_JSVAL ( JS_NewStringCopyN ( cx, data, res )) ,

NULL , NULL , JSPROP_ENUMERATE ) != 0 ) {

QUEUE_EXCEPTION ( "Internal error!" ) ;

Trang 35

Chú thích chương trình (1)

 Khi đặt các chú thích, nên dùng dấu // sẽ

không có ảnh hưởng khi chúng ta sử dụng cặp ký hiệu /* */ để vô hiệu hóa một đoạn lệnh trong quá trình sửa lỗi chương trình

Và trong C,C++ không cho phép các cặp

dấu /* */ lồng nhau

 Với các chú thích ngắn, ta có thể đặt nó

trên cùng dòng lệnh cần chú thích Với các chú thích dài hơn, hoặc chú thích cho cả

một đoạn lệnh, ta đặt chú thích trên một

Trang 36

Chú thích dài:

if (argc > 1) {

// Get input file from command line

if (freopen(argv[1], "r", stdin) == NULL)

error("can't open %s\n", argv[1]); }

Trang 38

Chú thích chương trình (4)

 Block: được sử dụng để mô tả file, hàm, thuật

toán được đặt ở đầu mỗi file, hàm Chúng

cũng có thể được đặt bên trong function,

method nhưng phải thụt vào cùng cấp với đoạn code

/*

* Here is a block comment.

*/

Trang 40

Chú thích chương trình (6)

 Trailing: là chú thích rất ngắn, thường xuất

hiện trên cùng dòng với dòng lệnh, và thường được dịch chuyển ra xa dòng lệnh Nếu có

nhiều trailing cùng xuất hiện trên một đoạn

lệnh thì chúng nên dịch chuyển thẳng hàng với nhau

Trang 41

Chú thích chương trình (7)

 End-Of-Line: // có thể đặt trên một dòng mới hoặc trên

cùng dòng với dòng lệnh Không nên dùng nhiều dòng liên tục cho text comment, nhưng cũng có thể dùng

nhiều dòng liên tục nếu chú thích nằm bên ngoài đoạn lệnh

Trang 43

Tự động tạo tài liệu (1)

 Tài liệu dùng để

 Duyệt toàn bộ thành phần của chương trình

 Thông tin của chương trình

 Nắm được cấu trúc chương trình

 Hiểu và dùng lại các module, các hàm

 Tự động tạo tài liệu

 Tiết kiệm thời gian

 Tạo tài liệu đầy đủ, hiệu quả

 Hỗ trợ định dạng đa dạng

Trang 44

Tự động tạo tài liệu (2)

(line x+2) * @Tag tagValue

(line x+3) * @Tag tagValue

(line x+y) * @Tag tagValue

(line x+y+1) */

Trang 45

(line 3) * Beginning of description

(line x) * end of description

Tự động tạo tài liệu (3)

 Mô tả chi tiết ý nghĩa của class,

interface, method, field.

 Giúp người đọc source code dễ hiểu hơn

Trang 46

Tự động tạo tài liệu (4)

 Tag:

 author (classes and interfaces only, required)

 version (classes and interfaces only, required)

 param (methods and constructors only)

 return (methods only)

 exception

 see

 since

 serial (or @serialField or @serialData)

(line x+y) * @Tag tagValue

Trang 47

Tự động tạo tài liệu (5)

/**

* Checks a object for "coolness" Performs a comprehensive

* coolness analysis on the object An object is cool if it

* inherited coolness from its parent; however, an object can

* also establish coolness in its own right.

*

* @param obj the object to check for coolness

* @param name the name of the object

* @return true if the object is cool; false otherwise.

* @exception OutOfMemoryError If there is not enough memory to

* determine coolness.

* @exception SecurityException If the security manager cannot be

* created

* @see isUncool

Trang 49

 Mã nguồn cần được thanh tra bởi bên thứ ba

 Mã nguồn nghiên cứu cần cải thiện bằng bên thứ

ba trước khi trở thành mã nguồn thương mại

 Mã nguồn không được dịch thành mã máy/mã

giả trước khi phân phối

Trang 51

Bảo mật hướng hành chính

 Chú thích, đặt tên riêng

 Đoạn giải thuật đặc trưng

 Kết hợp hai đặc trưng trên

Trang 52

Chú thích, đặt tên riêng

const double MYPI = 3.1415926 ;

//Print all primes in [t,cap]

void primes (int cap , int t , int composite) {

Trang 53

Đoạn giải thuật đặc trưng

int sum( int n){

int k = 0;

for ( int i=1;i<n;i++)

k = k+i;

return k;

for ( int i=1,s=0;i<n;s+=i,i++);

return s;

}

int sum( int n){

return n*(n+1)/2;

Trang 54

Hạn chế của bảo mật hướng hành chính

hiện mã nguồn đã bị đánh cắp

Trang 56

Đen tối hóa mã nguồn

obfuscating)

 Làm tối nghĩa của mã nguồn

 Phương pháp có thể làm bằng tay hay tự

động hóa

 Không thay đổi ngôn ngữ của mã nguồn

(không thay vai trò của compiler)

 Không xét đến việc trong sáng hóa mã

nguồn đã bị làm đen tối

Trang 57

Đen tối hóa mã nguồn

 Loại bỏ chú thích

 Mã hóa chuỗi

 Đổi tên định danh

 Sử dụng khai báo tiền xử lý

 Thay đổi truy xuất mảng

 Biến đổi biểu thức

 Biến đổi cấu trúc điều khiển

 Thay đổi cách gọi hàm

Trang 59

Mã hóa chuỗi

 Các hằng số chuỗi được mã hóa

 Chuỗi được khai báo bằng mảng số

 Sử dụng hàm giải mã chuỗi thay cho các vị trí sử

Trang 60

Đổi tên định danh

 Thay thế tên có nghĩa (tên hằng số, tên hàm, tên

biến, tên lớp,…) bằng tên vô nghĩa

void main() {

Trang 61

Sử dụng khai báo tiền xử lý

#else

#define T3 printf("Hello world!"); #include FILE

#endif

#else

#define T2 int main() { #include FILE

#endif

Trang 62

Thay đổi truy xuất mảng (1)

Với các ngôn ngữ hỗ trợ con trỏ như C, việc

truy xuất đến các phần tử mảng có thể được thực hiện theo nhiều cách

//declaration of array

int arr[]={0,1,2,3,4};

arr[idx]; //element <index> of array

arr; //base address of array

arr + idx; //pointer arithmetic

*(arr+idx); //<idx>th element

Trang 63

Thay đổi truy xuất mảng (2)

Với các ngôn ngữ hỗ trợ con trỏ như C, việc truy xuất đến các phần tử mảng có thể được thực hiện theo nhiều cách

void printarr( int integer) {

for ( int i=0; i<10; ++i) {

printf("%d ",*(( int *)integer+i));

}

}

void main() {

int array[]={0,1,2,3,4,5,6,7,8,9};

Trang 64

Biến đổi biểu thức

 Tối ưu hóa biểu thức

 Thay đổi thứ tự các phép toán trong biểu

Trang 65

Biến đổi cấu trúc điều khiển (1)

 Dùng cấu trúc tương đương

( for <-> while ) hoặc dùng biểu

thức thay cho điều kiện

 Dùng dấu phẩy cho các lệnh tuần

else {

c+=b; a=c+2; }

Trang 66

Biến đổi cấu trúc điều khiển (2)

 Dùng hàm đệ quy thay cho cấu trúc lặp

Trang 67

Thay đổi cách gọi hàm (1)

Trang 68

Thay đổi cách gọi hàm (2)

void f2( char *s){ }

void f5( double s){ }

void f9( int x, float f){ }

void callfunc ( int id, ){

Trang 69

else if(j == i && !composite) printf("%d\t",i);

else if(j > 1 && j < i) composite += !(i % j); }

} int main() { primes(100);

Trang 70

Ví dụ từ wikipedia (2)

void primes(int cap, int t, int

composite) { int i = t / cap;

int j = t % cap;

if(i <= 1) primes(cap,t+1,composite); else if(j == 0)

int main() { primes(100,0,0);

void primes(int cap) {

Trang 71

void primes(int cap, int t, int

int j = t % cap;

(i <= 1) ? primes(m,t+1,c) :

(j == 0) ? primes(m,t+1,0) : (j == i && !c) ?

(printf("%d\t",i),

primes(m,t+1,0)) : (j > 1 &&

j < i) ? primes(m,t+1,c + !(i % j)) :

(t < m * m) ? primes(m,t+1,c) : 0;

} int main() { primes(100,0,0);

Trang 72

void primes(int m, int t, int c)

primes(m,t+1,c) : !(t % m) ? primes(m,t+1,0) : ((t % m)==(t / m) && !c) ?

(printf("%d\t",(t / m)), primes(m,t+1,0)) :

((t % m)> 1 && (t % m) < (t /

m)) ? primes(m,t+1,c + !((t / m) % (t % m))) :

(t < m * m) ? primes(m,t+1,c)

: 0;

} int main() { primes(100,0,0);

}

Trang 73

void primes(int m, int t, int

_( , _+1, ) : !( _ % ) ? _( , _+1,0) :

(( _ % )==( _ / ) && !

) ? (printf("%d\t",( _ / )),

_( , _+1,0)) : (( _ % ) >

1 && ( _ % ) < ( _ / ))

? _( , _+1, + !(( _ / )

% ( _ % ))) : ( _ < * ) ?

_( , _+1, ) : 0;

}

Ví dụ từ wikipedia (5)

Trang 74

void _(int , int _, int ) {

Ví dụ từ wikipedia (6)

Xóa các khoảng trắng và dấu ngoặc

Trang 75

Đánh giá đen tối hóa mã nguồn

 Ưu điểm

 Bảo vệ sở hữu trí tuệ trong mã nguồn

 Giảm việc bị khám phá lỗ hổng qua mã nguồn

 Giảm kích thước mã nguồn

 Loại bỏ lỗi thiếu thư viện

 Nhược điểm

 Tăng độ khó dịch ngược (reverse engine) nhưng

không phải là không thể

 Không uyển chuyển (portability)

Trang 77

 The International Obfuscated C Code Contest

 http://www1.us.ioccc.org/main.html

 Goals of the Contest

 To write the most Obscure/Obfuscated C

program

 To show the importance of programming

style, in an ironic way

 To stress C compilers with unusual code

 To illustrate some of the subtleties of the C

language

Trang 78

!(OO-!I||I)?l-1:OO :(OO=main(I,O,O0,OO>>!!OO,l),

!(OO-l+!I||I)?l-1:main(I-!I-!!I,O,OO,OO,l)) :(O0+OO)%l

:main(I-I/I-I/I,O,O0,OO+OO/OO,

main(0,O,O0,OO,I-I-I)+I+1?1:printf("%d ",I-I-I) +fflush(stdout))

John Dalbec

In ra các số nguyên tố nhỏ hơn 14748 (1996)

Trang 80

Ví dụ trên IOCC (3)

#include <stdio.h>

int l; int main( int o, char **O,

int I){ char c,*D=O[1]; if (o>0){

Trang 81

char *O=" <60>!?\\\n"_ doubIe[010]_ int0,int1 _ Iong=0 _ inIine( int eIse){ int

O1O=!O _ l=!O; for (;O1O<010;++O1O)l+=(O1O[doubIe]*pow(eIse,O1O)); return l;} int

main( int booI, char *eIse[]){ int I=1,x=-*O; if (eIse){ for (;I<010+1;I++)I[doubIe-1]

=booI>I?atof(I[eIse]):!O switch (*O)x++)abs(inIine(x))>Iong&&(Iong=abs(inIine(x

Jonathan Hoyle

Vẽ đồ thị hàm số (2004)

Ngày đăng: 29/06/2015, 14:17

TỪ KHÓA LIÊN QUAN

w