Trạng Quỳnh luận về trọng dụng nhân tài


Mình đã có một giấc mơ kỳ lạ. Đó là được hầu chuyện Trạng Quỳnh. Trong mơ, Ngài đã luận về một chuyện rất thời sự: Trọng dụng nhân tài. Câu chuyện nửa hư, nửa thưc, như mới, như cũ cứ ám ảnh mình mãi, đành ghi lại để mọi người tham khảo.

(Minh họa: Ngọc Diệp)

Thưa Quan Trạng, hậu thế vẫn không ngừng tranh cãi quê hương của Ngài.  Vậy rốt cuộc, Ngài quê ở thôn nào, xã nào vậy?

Hơ! Lũ hậu thế các anh thật là lắm chuyện. Ta sinh ở đâu nào có vấn đề gì? Đơn giản ta là công dân nước Việt Nam văn hiến, con của bà mẹ Văn học dân gian.

Ngài là con của Bà mẹ Văn học dân gian…?

Đúng. Đó là một bà mẹ kỳ lạ. Khi dòng văn học chính thống đủ tâm, đủ tầm, đủ trí tuệ và bản lĩnh đảm đương được sứ mệnh là phản ánh trung thực thời cuộc cũng như những khát vọng sâu kín của quần chúng nhân dân thì dòng văn học dân gian lắng xuống. Còn ngược lại, khi dòng văn học chính thống hời hợt, xa lạ nguyện ước của nhân dân thì khi ấy, dòng văn học dân gian sẽ đẻ ra những đứa con tinh thần để gánh vác sứ mệnh và duy trì sự liên tục dòng chảy của văn chương…

Và trên dòng chảy văn chương ấy, có một Quan Trạng Nguyễn Quỳnh chèo đò trên sông và một thi nhân Đoàn Thị Điểm bán quán nước ở bến đò?

Đúng thế, dù thực chất cô Điểm bán hàng ở bến sông khác.

Dạo còn chăn trâu trên, tôi đọc chuyện đối đáp “Sấm động Nam bang – Vũ qua Bắc hải” giữa Trạng và sứ Tầu, sướng chêt mê chết mệt. Nhất là đoạn kết, sứ Tầu sợ xanh mắt vì người bán quán, chèo đò nước Nam ta còn tài đến thế, huống hồ…

Ngốc ơi là ngốc. Đấy là chuyện ngụ ngôn.

Truyện ngụ ngôn? Truyện ngụ ngôn là phải rút ra bài học mà tôi không thấy bài học gì ở đây cả?

Nó có một thông điệp về sử dụng nhân tài. Nếu sứ Tàu nghĩ rằng: “Trời ơi, những nhân tài như Trạng Quỳnh và Đoàn Thị Điểm đến nước Trung Hoa rộng lớn còn đếm trên đầu ngón tay mà ở xứ An Nam này, họ lại phải đi chèo đò, bán quán!? Lãng phí nhân tài, bỏ rơi nhân tài, đầy đọa nhân tài đến thế này ru!”. Đó cũng là bài học cho hôm nay, khi mà hiện tượng người có tài không được trọng dụng đang có nguy cơ tái phát…

Thưa Quan Trạng, có lẽ ngài nói sao chứ hiện nay, ngành ngành trải thảm đỏ, bộ bộ trải thảm đỏ, tỉnh tỉnh trải thảm đỏ, huyện huyện trải thảm đỏ… Xem ra cả nước đang tưng bừng thảm đỏ để đón rước nhân tài.

Hơ! Hơ! Hơ! Hơ! Ta đã nghe nhiều đến cái gọi là “phong trào trải thảm đỏ” này lắm rồi. Nhưng nói là một chuyện mà làm lại là chuyện khác, rất khác. Khác vì họ nói thế nhưng họ liệu có đón thật không? Đón về rồi có dùng không? Dùng có thật lòng không, có tin cậy không? Mà ta nói thật, tài năng thì hiếm lắm nhưng tài vừa vừa thì chả thiếu. Ngành nào, địa phương nào cũng có. Chỉ cần sử dụng được hết cái số tài vừa vừa thì đã tốt đẹp lắm rồi.

Nghĩa là…

Nghĩa là hãy thật lòng trọng dụng những tài năng có ở ngành mình, địa phương mình, cơ quan mình đi đã. Hãy cho họ được sáng tạo thì không cần trải thảm đỏ, thảm xanh, thảm vàng… Xin đừng đẩy người tài vào “thảm… cảnh” đã là may lắm rồi. Mà thiên hạ tinh lắm. Người ta không tin anh thực lòng trọng dụng nhân tài nếu như tài năng ở chính cơ quan anh, địa phương anh, bộ ngành anh… chưa được trọng dụng.

Thưa, ngài qua đời đã mấy trăm năm nhưng tường tỏ việc nhân gian như người trong cuộc… Xin Ngài chỉ giáo nên làm thế nào để người tài được trọng dụng, để người tài thật sự được đóng góp công sức của mình vào sự nghiệp xây dựng và bảo vệ Tổ quốc?

Ta đã nói rồi. Hãy hỏi nhân dân ấy. Trong nhân dân không thiếu gì nhân tài. Mà ngươi hãy hỏi chính độc giả Dân trí ấy. Ta thấy các ý kiến của họ rất sâu sắc về nhiều lĩnh vực đấy. Hãy “trọng dụng” họ, những người bạn thân quen của Dân trí là đủ lắm rồi.

Dạ, xin cám ơn Quan Trạng! Vâng lời Ngài, con xin về hỏi những độc giả của chúng con ạ.

Độc giả Dân trí thân mến! Các bạn hãy giúp tôi tìm câu trả lời này!

Bùi

Theo : Dân trí

ASCII Table and Description


ASCII stands for American Standard Code for Information Interchange. Computers can only understand numbers, so an ASCII code is the numerical representation of a character such as ‘a’ or ‘@’ or an action of some sort. ASCII was developed a long time ago and now the non-printing characters are rarely used for their original purpose. Below is the ASCII character table and this includes descriptions of the first 32 non-printing characters. ASCII was actually designed for use with teletypes and so the descriptions are somewhat obscure. If someone says they want your CV however in ASCII format, all this means is they want ‘plain’ text with no formatting such as tabs, bold or underscoring – the raw format that any computer can understand. This is usually so they can easily import the file into their own applications without issues. Notepad.exe creates ASCII text, or in MS Word you can save a file as ‘text only’

 

image

Extended ASCII Codes

 

extend

Trim a string using C


#include <ctype.h>
#include <string.h>
#include <stdio.h>
#define NUL ”
char *trim(char *str)
{
      char *ibuf = str, *obuf = str;
      int i = 0, cnt = 0;
      if (str)
      {
           for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf);
            if (str != ibuf)
                  memmove(str, ibuf, ibuf – str);          
            while (*ibuf)
            {
                  if (isspace(*ibuf) && cnt)
                        ibuf++;
                  else
                  {
                        if (!isspace(*ibuf))
                              cnt = 0;
                        else
                        {
                              *ibuf = ‘ ‘;
                              cnt = 1;
                        }
                        obuf[i++] = *ibuf++;
                  }
            }
            obuf[i] = NUL;
            while (–i >= 0)
            {
                  if (!isspace(obuf[i]))
                        break;
            }
            obuf[++i] = NUL;
      }
      return str;
}
void main(int argc, char *argv[])
{
    char s[1000]="  Anh      yeu         em ";
      printf("trim(\"%s\") ", s);
      printf("returned \"%s\"\n", trim(s));
}

C or C++ Using the Windows API


C and C++ programs that use the Windows API functions consist of a main program, a window procedure, and possibly your own additional functions. The main program, which must be called WinMain(), sets up the window class (not to be confused with a C++ class), creates and initially displays the window, and manages the message loop. The window procedure, which will be called WindowProc() in all our examples, processes the messages it receives from Windows.

/****************************************************************************\
*                                                                            *
*  First.c                                                                   *
*                                                                            *
*  This is the first Fastgraph for Windows example program. It demonstrates  *
*  tasks common to most Fastgraph for Windows programs and serves as a       *
*  template for building the other examples.                                 *
*                                                                            *
\****************************************************************************/
#include <fgwin.h>
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdParam, int iCmdShow)
{
   static char szAppName[] = "FGfirst";
   HWND        hWnd;
   MSG         msg;
   WNDCLASSEX  wndclass;
   wndclass.cbSize        = sizeof(wndclass);
   wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
   wndclass.lpfnWndProc   = WindowProc;
   wndclass.cbClsExtra    = 0;
   wndclass.cbWndExtra    = 0;
   wndclass.hInstance     = hInstance;
   wndclass.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
   wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);
   wndclass.hbrBackground = NULL;
   wndclass.lpszMenuName  = NULL;
   wndclass.lpszClassName = szAppName;
   wndclass.hIconSm       = LoadIcon(NULL,IDI_APPLICATION);
   RegisterClassEx(&wndclass);
   hWnd = CreateWindow(szAppName, // window class name
      "First Fastgraph for Windows Program", // window caption
      WS_OVERLAPPEDWINDOW,     // window style
      CW_USEDEFAULT,           // initial x position
      CW_USEDEFAULT,           // initial y position
      CW_USEDEFAULT,           // initial x size
      CW_USEDEFAULT,           // initial y size
      NULL,                    // parent window handle
      NULL,                    // window menu handle
      hInstance,               // program instance handle
      NULL);                   // creation parameters
   ShowWindow(hWnd,iCmdShow);
   UpdateWindow(hWnd);
   while (GetMessage(&msg,NULL,0,0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   return msg.wParam;
}
/****************************************************************************\
*                                                                            *
*  WindowProc                                                                *
*                                                                            *
*  Window procedure to handle messages sent to the window.                   *
*                                                                            *
\****************************************************************************/
HDC      hDC;
HPALETTE hPal;
int      hVB;
UINT     cxClient, cyClient;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
   PAINTSTRUCT ps;
   switch (iMsg)
   {
      case WM_CREATE:
         hDC = GetDC(hWnd);
         fg_setdc(hDC);
         hPal = fg_defpal();
         fg_realize(hPal);
         fg_vbinit();
         hVB = fg_vballoc(640,480);
         fg_vbopen(hVB);
         fg_vbcolors();
         fg_setcolor(19);
         fg_fillpage();
         return 0;
      case WM_PAINT:
         BeginPaint(hWnd,&ps);
         fg_vbscale(0,fg_getmaxx(),0,fg_getmaxy(),0,cxClient-1,0,cyClient-1);
         EndPaint(hWnd,&ps);
         return 0;
      case WM_SETFOCUS:
         fg_realize(hPal);
         InvalidateRect(hWnd,NULL,TRUE);
         return 0;
      case WM_SIZE:
         cxClient = LOWORD(lParam);
         cyClient = HIWORD(lParam);
         return 0;
      case WM_DESTROY:
         fg_vbclose();
         fg_vbfree(hVB);
         fg_vbfin();
         DeleteObject(hPal);
         ReleaseDC(hWnd,hDC);
         PostQuitMessage(0);
         return 0;
   }
   return DefWindowProc(hWnd,iMsg,wParam,lParam);
}

First, notice the directive at the beginning of the program:

#include <fgwin.h>

 

The FGWIN.H header file contains Fastgraph’s function prototypes and symbolic constant definitions. It also force-includes the WINDOWS.H header file if necessary. This statement will appear in the C and C++ versions of all Fastgraph example programs.

Now let’s look at WinMain(). WinMain() first sets up a window class that defines the window characteristics and associates a window procedure with the class. It then calls the CreateWindow() Windows API function to create a window based on that window class (this also generates the WM_CREATE message). CreateWindow() returns a window handle, which we store in the variable hWnd, for use elsewhere in the program. Next, the Windows API function ShowWindow() initially displays the window, and another Windows API function, UpdateWindow(), then generates the first WM_PAINT message to display the window contents. The remainder of WinMain() is a while loop implementing the message loop. The message loop retrieves messages Windows sends to the program and sends these to the program’s window procedure for processing. The message loop executes until the user exits the program. Note that we’ve exclusively used Windows API functions to handle the details of WinMain().

The window procedure WindowProc() is where most of the action takes place and provides our first look at some Fastgraph functions. Note that our program does not explicitly call WindowProc(). Instead, it is called by Windows in response to events such as creating or resizing the window. The message loop passes these events to WindowProc() as messages, which WindowProc() processes through its own distinct message handlers. WindowProc() implements the message handlers as a switch and case construct. Our window procedure includes WM_CREATE, WM_PAINT, WM_SETFOCUS, WM_SIZE, and WM_DESTROY message handlers, which we’ll now discuss in detail.

Windows generates a WM_CREATE message when it first creates the program’s window. Only one WM_CREATE message typically occurs per program instance, so it is a good place for any application-specific initialization code. Our WM_CREATE message handler first calls the Windows API function GetDC() to obtain a device context to the window’s client area and then calls fg_setdc() to make the device context available to other Fastgraph functions:

hDC = GetDC(hWnd);
fg_setdc(hDC);

 

Next, it creates and realizes the default logical palette:

hPal = fg_defpal();

fg_realize(hPal);

The WM_CREATE message handler then initializes Fastgraph’s virtual buffer environment, creates a 640×480 virtual buffer and makes it the active virtual buffer, and assigns the logical palette colors to the virtual buffer:

fg_vbinit();

hVB = fg_vballoc(640,480);

fg_vbopen(hVB);

fg_vbcolors();

Finally, we fill the virtual buffer with blue pixels (color 19 is blue when using Fastgraph’s default 256-color virtual buffers with the default logical palette):

fg_setcolor(19);

fg_fillpage();

Windows generates a WM_PAINT message when the window’s client area must be repainted. Our WM_PAINT handler begins with a call to the Windows API function BeginPaint(), then calls fg_vbscale() to display the contents of the 640×480 virtual buffer scaled to the size of the client area, and ends with a call to the Windows API function EndPaint(). This sequence is typical of WM_PAINT message handlers in Fastgraph programs.

Windows generates a WM_SETFOCUS message when the window gains the input focus. This most often happens when the window becomes the active or top-level window. Our WM_SETFOCUS handler first calls fg_realize() to activate the program’s logical palette (in case another program has changed the logical palette colors), then calls the Windows API function InvalidateRect() to force a WM_PAINT message to redraw the client area. This sequence is typical of WM_SETFOCUS message handlers in Fastgraph programs.

Windows generates a WM_SIZE message whenever the size of the window changes, and also upon creation of a window. Our WM_SIZE handler simply saves the new width and height of the client area (in pixels) in the variables cxClient and cyClient. These quantities are passed to fg_vbscale() in the WM_PAINT message handler.

Windows generates a WM_DESTROY message after removing a window to signal a program exit. Our WM_DESTROY handler first closes the virtual buffer, releases its memory, and terminates virtual buffer processing:

fg_vbclose();

fg_vbfree(hVB);

fg_vbfin();

It then calls three Windows API functions to delete the logical palette created with fg_defpal(), release the device context created with GetDC(), and exit:

DeleteObject(hPal);

ReleaseDC(hWnd,hDC);

PostQuitMessage(0);

Finally, our window procedure ends with a call to the Windows API function DefWindowProc(). This provides default message processing for the hundreds of other Windows message types not explicitly handled by the window procedure.

Source : fastgraph.com

Nghe tớ nói, nhưng đừng tin nhé!


Hắn nhìn vào mắt tôi. Thật kỳ lạ. Có cảm giác chân thành lắm. Lời nói có thể giả, nhưng ánh mắt này…

Một ngày thời cấp 1, trở về nhà, mẹ bảo tôi rằng nhà chúng tôi có hàng xóm mới.

Tò mò, tôi chạy ra bờ tường, ngó cổ sang xem.

– Ê! Nhóc! Làm cái gì thậm thụt thế? – Tiếng nói ở đâu vang lên khiến tôi giật mình, trượt chân té ngửa.

Toàn thân xây xước, đấy chính là món quà gặp mặt mà tên hàng xóm mới chết tiệt thân ái tặng cho tôi.

Thế là, tôi nghiêm túc quyết định, hắn chính là kẻ thù lớn của tôi trong cuộc đời này. Dù cho vào ngày ấy, “cuộc đời” là cái gì thì tôi vẫn còn mơ hồ lắm.

– Ê! Cậu dậy sớm thế, sang đây chơi đi!

Cậu ta gọi với sang, trong khi tôi vẫn còn mắt nhắm mắt mở ở sân giếng đánh răng.

Tôi kệ. Cái đồ con trai gì mà suốt ngày (giả vờ) nói nói cười cười.

– Sang đây đi! Nhà tớ có quả dừa to lắm. Mình bổ ra uống nước. Nước dừa mát rượi.

Băn khoăn.

Ngẫm nghĩ.

Kết luận.

– Ừ thì sang!

Tôi lon ton chạy sang. Thấy hắn vô tư cười và chỉ tay lên cao. Đúng là có dừa. Nhưng mà chót vót trên cây. Quả lại bé tẹo. Tôi bị lừa rồi. Cái thứ chết bầm. Tôi thề quyết tâm không bao giờ nghe bất cứ thứ gì từ miệng hắn nữa.

kiemtra1007114_42d28

Mà hình như, hắn có hiểu được lỗi lầm của mình thì phải, mấy hôm sau, chẳng thấy hắn nói thêm lời nào, cười cũng không.

Đáng ra thì, tôi nên hả hê mới phải. Nhưng cứ cảm giác khó hiểu sao sao, tôi rụt rè hỏi:

– Cậu làm sao thế?

– Tớ, tớ sắp phải chuyển đi rồi. Mẹ tớ bảo ở đây không hợp, mọi người đều không thích tớ.

Chuyển đi? Sao lại thế? Đúng là tôi có không ưa hắn thật. Nhưng mà tự nhiên đi thế này, cũng thấy buồn ghê ấy.

– Không. Tớ không ghét cậu mà. À, cũng có một tẹo, nhưng mà…nói chung là không ghét lắm đâu.

– Thế tức là, cậu vẫn ghét tớ hả?

Nhìn mặt hắn buồn thiu, tôi thấy thật có lỗi. Im lặng một lúc, tôi quay sang hắn:

– Không. Tớ không ghét tí nào. Thế bao giờ cậu đi?

– Tớ không đi nữa. Cậu có ghét tớ đâu mà tớ phải đi– Hắn ngoác miệng cười. Nụ cười gian xảo quen thuộc – Tớ đùa cậu đấy. Đừng nghe tớ nói chứ. Sao mà dễ tin người thế!

Nói xong hắn chạy biến, bỏ mặc tôi với bộ mặt đỏ gay xì khói ra tai.

Hóa ra mấy ngày vừa rồi hắn bị lên sởi, nên phải đóng cửa ở trong nhà. Tôi trân trọng thề bằng tất cả sự căm tức đang dồn lên tận đỉnh: từ nay trở đi tuyệt đối không tin bất cứ thứ gì phát ra từ miệng hắn.

Ấy thế mà, thời thơ ấu của tôi đều đặn trải qua bằng việc nghe hắn nói, tin sái cổ, và cuối cùng bị lừa.

– Tớ đã bảo rồi, nghe tớ nói, nhưng đừng tin tớ nhé!

Mỗi lần như vậy hắn đều cười đắc ý, còn tôi, trở lên vô cảm với lời hắn nói rồi.

Ngày chuẩn bị thi đại học, hắn bảo tôi thế này:

– Chúc cậu thi tốt! Chúng mình sẽ cùng đỗ nhé! Nói thật đấy!

Tôi cười:

– Ừ! Tớ cũng chúc cậu thi tốt. Nhưng đừng có tin nhé! – Nói rồi, tôi thản nhiên quay đi.

Đột nhiên, hắn hét thật to, sau lưng tôi:

– Tớ thích cậu!

Một chút bất ngờ, nhưng tôi nhanh chóng quay lại cười:

– Thế à? Tớ không tin đâu.

Kết quả báo về. Tôi đỗ. Hắn trượt. Nhưng hắn cũng chẳng tỏ ra buồn phiền cho lắm. Hắn nộp hồ sơ vào một trường cao đẳng ở quê. Còn tôi lên Hà Nội học. Chúng tôi ít gặp nhau hơn.

Nhưng mỗi ngày cuối tuần trở về nhà, tôi và hắn đều trò chuyện với nhau. Mỗi người đều có những câu chuyện trường lớp mới và cuộc sống hiện tại xung quanh mình. Tất nhiên, phải tuân theo điều kiện thỏa thuận trước: “Nói thật!”

– Này!

– Sao thế?– Tôi quay sang hắn.

– Tớ thích cậu!

– Ha ha ha…-Tôi cười lớn – Cậu quên là giờ vẫn phải nói thật à?

Tôi tròn mắt nhìn hắn. Không hiểu cái biểu cảm nghiêm túc lúc này có nghĩa là gì đây?

– Tớ thích cậu!

Hắn nhìn vào mắt tôi. Thật kỳ lạ. Có cảm giác chân thành lắm. Lời nói có thể giả, nhưng ánh mắt này…

– Tớ thích cậu! Thật đấy! Nghe tớ nói, và tin tớ nhé…

Nguồn : Mực Tím

Mã hóa chuỗi kết nối vào webconfig trong Nhibernate


Thông thường khi sử dụng Nhibernate để phát triển ứng dụng web hay ứng dụng winform chúng ta thường bỏ chuỗi kết nối ở file hibernate.cfg.xml , mình thấy bỏ thế nào không an toàn nên sau khi google với tìm hiểu mình đã tìm ra cách để bỏ vào webconfig và mã hóa chuỗi kết nối này cho nó an toàn nhằm tránh shell 爆笑

Thông thường thì chuỗi kết nối cơ sở dữ liệu thường bỏ ở file hibernate.cfg.xml như sau :

<property name="connection.connection_string">
      Chuỗi kết nối cơ sở dữ liệu ở đây

    </property>

Để mã hóa chuỗi kết nối ta viết một lớp là Crypto để mã hóa và giải mã trước đã

public static class Crypto
   {
       const string InitialVector = "4AQYuEmZ3Q7gNHdj";       
       public static string Encrypt(string data,string pass)
       {
           if (string.IsNullOrEmpty(data)) return "";

           var initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
           var plainTextBytes = Encoding.UTF8.GetBytes(data);
           var keyBytes = Encoding.ASCII.GetBytes(pass);

           var symmetricKey = new RijndaelManaged();
           symmetricKey.Mode = CipherMode.CBC;
           byte[] cipherTextBytes = null;
           using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes))
           {
               using (var memStream = new MemoryStream())
               {
                   using (var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                   {
                       cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                       cryptoStream.FlushFinalBlock();
                       cipherTextBytes = memStream.ToArray();
                       memStream.Close();
                       cryptoStream.Close();
                   }
               }
           }
           symmetricKey.Clear();
           return Convert.ToBase64String(cipherTextBytes);         
       }     
       public static string Decrypt(string data,pass)
       {
           if (string.IsNullOrEmpty(data)) return "";

           var initialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
           var cipherTextBytes = Convert.FromBase64String(data);
           var keyBytes = Encoding.ASCII.GetBytes(pass);

           var symmetricKey = new RijndaelManaged();
           symmetricKey.Mode = CipherMode.CBC;
           var plainTextBytes = new byte[cipherTextBytes.Length];
           var byteCount = 0;
           using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes))
           {
               using (var memStream = new MemoryStream(cipherTextBytes))
               {
                   using (var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                   {
                       byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                       memStream.Close();
                       cryptoStream.Close();
                   }
               }
           }
           symmetricKey.Clear();
           return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);           
       }    
   }

Mục đích của lớp này là mã hóa theo pass và giải mã theo pass một chuỗi, mục đích là mã hóa chuỗi kết nối.

Để sửa lại phương thức lấy chuỗi kết nối ta override lại lớp NHibernate.Connection.DriverConnectionProvider như sau :

public class MyConnectionProvider : NHibernate.Connection.DriverConnectionProvider
    {
        static string conn = "";
        protected override string ConnectionString
        {
            get
            {
                if (string.IsNullOrEmpty(conn))
                {

                    string connectionString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
                    conn= Crypto.Decrypt(connectionString,"sokhanh03");
                }
                return conn;
            }
        }       
       
    }

Sửa file hibernate.cfg.xml như sau :

<property name="connection.provider">
      (Name space của MyConnectionProvider).MyConnectionProvider,Name space của MyConnectionProvider
      <!–NHibernate.Connection.DriverConnectionProvider–>
    </property>

Chú ý comment lại dòng NHibernate.Connection.DriverConnectionProvider

Sau đó vào file webconfig hay app.config sửa lại thành :

<connectionStrings>
        <add name="ApplicationServices" connectionString="Chuỗi kết nối đã mã hóa với pass là sokhanh03" providerName="System.Data.SqlClient"/>
    </connectionStrings>

Như vậy ta đã chuyển chuỗi kết nối từ file hibernate.cfg.xml sang file webconfig(app.config) đã mã hóa, sau đó tiến hành code bình thường.

Mục đích của việt này là tránh việc bị shell đọc file webconfig và lấy chuỗi kết nối

Chúc các bạn thành công!

Nếu vẫn không làm được vui lòng comment lại ở đây mình sẽ support cho 爆笑

The Syntax of C and C++ Function Pointers


Define a Function Pointer

Regarding their syntax, there are two different types of function pointers: On the one hand there are pointers to ordinary C functions or to static C++ member functions. On the other hand there are pointers to non-static C++ member functions. The basic difference is that all pointers to non-static member functions need a hidden argument: The this-pointer to an instance of the class. Always keep in mind: These two types of function pointers are incompatible with each other.

Since a function pointer is nothing else than a variable, it must be defined as usual. In the following example we define three function pointers named pt2Function, pt2Member and pt2ConstMember. They point to functions, which take one float and two char and return an int. In the C++ example it is assumed, that the functions, our pointers point to, are (non-static) member functions of TMyClass.

int (*pt2Function)(float, char, char) = NULL;                        // C
int (TMyClass::*pt2Member)(float, char, char) = NULL;                // C++
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;     // C++
Calling Convention

Normally you don’t have to think about a function’s calling convention: The compiler assumes __cdecl as default if you don’t specify another convention. However if you want to know more, keep on reading … The calling convention tells the compiler things like how to pass the arguments or how to generate the name of a function. Some examples for other calling conventions are __stdcall, __pascal and __fastcall. The calling convention belongs to a function’s signature: Thus functions and function pointers with different calling convention are incompatible with each other! For Borland and Microsoft compilers you specify a specific calling convention between the return type and the function’s or function pointer’s name. For the GNU GCC you use the __attribute__ keyword: Write the function definition followed by the keyword __attribute__ and then state the calling convention in double parentheses. If someone knows more: Let me know😉 And if you want to know how function calls work under the hood you should take a look at the chapter Subprograms in Paul Carter’s PC Assembly Tutorial.

void __cdecl DoIt(float a, char b, char c);                             // Borland and Microsoft
void         DoIt(float a, char b, char c)  __attribute__((cdecl));     // GNU GCC
Assign an address to a Function Pointer

It’s quite easy to assign the address of a function to a function pointer. You simply take the name of a suitable and known function or member function. Although it’s optional for most compilers you should use the address operator & infront of the function’s name in order to write portable code. You may have got to use the complete name of the member function including class-name and scope-operator (::). Also you have got to ensure, that you are allowed to access the function right in scope where your assignment stands.


//assign an address to the function pointer
//     Note: Although you may ommit the address operator on most compilers
//     you should always use the correct way in order to write portable code.

// C
int DoIt  (float a, char b, char c){ printf("DoIt\n");   return a+b+c; }
int DoMore(float a, char b, char c)const{ printf("DoMore\n"); return a-b+c; }

pt2Function = DoIt;      // short form
pt2Function = &DoMore;   // correct assignment using address operator
// C++
class TMyClass
{
public:
   int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
   int DoMore(float a, char b, char c) const
         { cout << "TMyClass::DoMore" << endl; return a-b+c; };

   /* more of TMyClass */
};

pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator
pt2Member = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
Comparing Function Pointers

You can use the comparison-operators (==, !=) the same way as usual. In the following example it is checked, whether pt2Function and pt2Member actually contain the address of the functions DoIt and TMyClass::DoMore. A text is shown in case of equality.

//  comparing function pointers

// C
if(pt2Function >0){                           // check if initialized
   if(pt2Function == &DoIt)
      printf("Pointer points to DoIt\n"); }
else
   printf("Pointer not initialized!!\n");


// C++
if(pt2ConstMember == &TMyClass::DoMore)
   cout << "Pointer points to TMyClass::DoMore" << endl;
Calling a Function using a Function Pointer

In C you call a function using a function pointer by explicitly dereferencing it using the * operator. Alternatively you may also just use the function pointer’s instead of the funtion’s name. In C++ the two operators .* resp. ->* are used together with an instance of a class in order to call one of their (non-static) member functions. If the call takes place within another member function you may use the this-pointer.

//------------------------------------------------------------------------------------
//  How to Return a Function Pointer
//     'Plus' and 'Minus' are defined above. They return a float and take two float


// Direct solution: Function takes a char and returns a pointer to a
// function which is taking two floats and returns a float. <opCode>
// specifies which function to return
float (*GetPtr1(const char opCode))(float, float)
{
   if(opCode == '+')
      return &Plus;
   else
      return &Minus; // default if invalid operator was passed
}


// Solution using a typedef: Define a pointer to a function which is taking
// two floats and returns a float
typedef float(*pt2Func)(float, float);

// Function takes a char and returns a function pointer which is defined
// with the typedef above. <opCode> specifies which function to return
pt2Func GetPtr2(const char opCode)
{
   if(opCode == '+')
      return &Plus;
   else
      return &Minus; // default if invalid operator was passed
}


// Execute example code
void Return_A_Function_Pointer()
{
   cout << endl << "Executing 'Return_A_Function_Pointer'" << endl;

   // define a function pointer and initialize it to NULL
   float (*pt2Function)(float, float) = NULL;

   pt2Function=GetPtr1('+');   // get function pointer from function 'GetPtr1'
   cout << (*pt2Function)(2, 4) << endl;   // call function using the pointer


   pt2Function=GetPtr2('-');   // get function pointer from function 'GetPtr2'
   cout << (*pt2Function)(2, 4) << endl;   // call function using the pointer
}
How to Use Arrays of Function Pointers ?

Operating with arrays of function pointers is very interesting. This offers the possibility to select a function using an index. The syntax appears difficult, which frequently leads to confusion. Below you find two ways of how to define and use an array of function pointers in C and C++. The first way uses a typedef, the second way directly defines the array. It’s up to you which way you prefer.

//------------------------------------------------------------------------------------
// 2.8 How to Use Arrays of Function Pointers

// C ---------------------------------------------------------------------------------

// type-definition: 'pt2Function' now can be used as type
typedef int (*pt2Function)(float, char, char);

// illustrate how to work with an array of function pointers
void Array_Of_Function_Pointers()
{
   printf("\nExecuting 'Array_Of_Function_Pointers'\n");

   // define arrays and ini each element to NULL, <funcArr1> and <funcArr2> are arrays
   // with 10 pointers to functions which return an int and take a float and two char

   // first way using the typedef
   pt2Function funcArr1[10] = {NULL};

   // 2nd way directly defining the array
   int (*funcArr2[10])(float, char, char) = {NULL};


   // assign the function's address - 'DoIt' and 'DoMore' are suitable functions
   // like defined above in 2.1-4
   funcArr1[0] = funcArr2[1] = &DoIt;
   funcArr1[1] = funcArr2[0] = &DoMore;

   /* more assignments */

   // calling a function using an index to address the function pointer
   printf("%d\n", funcArr1[1](12, 'a', 'b'));         //  short form
   printf("%d\n", (*funcArr1[0])(12, 'a', 'b'));      // "correct" way of calling
   printf("%d\n", (*funcArr2[1])(56, 'a', 'b'));
   printf("%d\n", (*funcArr2[0])(34, 'a', 'b'));
}


// C++ -------------------------------------------------------------------------------

// type-definition: 'pt2Member' now can be used as type
typedef int (TMyClass::*pt2Member)(float, char, char);

// illustrate how to work with an array of member function pointers
void Array_Of_Member_Function_Pointers()
{
   cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;

   // define arrays and ini each element to NULL, <funcArr1> and <funcArr2> are
   // arrays with 10 pointers to member functions which return an int and take
   // a float and two char

   // first way using the typedef
   pt2Member funcArr1[10] = {NULL};

   // 2nd way of directly defining the array
   int (TMyClass::*funcArr2[10])(float, char, char) = {NULL};


   // assign the function's address - 'DoIt' and 'DoMore' are suitable member
   //  functions of class TMyClass like defined above in 2.1-4
   funcArr1[0] = funcArr2nd use an array of function pointers in C and C++.
 The first way uses a typedef, the second way directly defines the array. It's up to you which way you prefer.
[1] = &TMyClass::DoIt;
   funcArr1[1] = funcArr2[0] = &TMyClass::DoMore;
   /* more assignments */

   // calling a function using an index to address the member function pointer
   // note: an instance of TMyClass is needed to call the member functions
   TMyClass instance;
   cout << (instance.*funcArr1[1])(12, 'a', 'b') << endl;
   cout << (instance.*funcArr1[0])(12, 'a', 'b') << endl;
   cout << (instance.*funcArr2[1])(34, 'a', 'b') << endl;
   cout << (instance.*funcArr2[0])(89, 'a', 'b') << endl;
}