Что имя искажает, и как оно работает?

Запишите обратный прокси на апачском сервере перед Вашим приложением, которое реализует Tarpit (Статья Википедии) для наказания ботов. Это просто управляло бы списком IP-адресов, которые соединились за последние несколько секунд. Вы обнаруживаете пакет запросов от единственного IP-адреса и затем экспоненциально задерживаете те запросы перед ответом.

, Конечно, несколько человек могут произойти из того же IP-адреса, если бы они находятся на сетевом соединении NAT'd, но маловероятно, что человек возражал бы против Вашего времени отклика, идя для 2 мс в 4 мс (или даже 400 мс), тогда как боту будет препятствовать увеличивающаяся задержка довольно быстро.

42
задан Stefano Borini 22 August 2009 в 01:55
поделиться

5 ответов

В выбранном вами языке программирования, если идентификатор экспортируется из отдельно скомпилированного модуля, ему требуется имя, под которым он известен во время компоновки. Изменение имени решает проблему перегруженных идентификаторов в языках программирования. (Идентификатор «перегружен», если одно и то же имя используется в более чем одном контексте или имеет более одного значения.)

Некоторые примеры:

  • В C ++ функция или метод get могут быть перегружены в нескольких типах.

  • В Ada или Modula-3 функция get может появляться в нескольких модулях.

Несколько типов и несколько модулей охватывают обычные контексты.

Типичные стратегии:

  • ] Сопоставьте каждый тип со строкой и используйте объединенный высокоуровневый идентификатор и «строку типа» в качестве имени времени ссылки. Часто встречается в C ++ (особенно просто, поскольку перегрузка разрешена только для функций / методов и только для типов аргументов) и Ada (где вы также можете перегрузить типы результатов).

  • Если идентификатор используется более чем в одном модуле или пространстве имен, соедините имя модуля с именем идентификатора, например, List_get вместо List.get .

В зависимости от того, какие символы допустимы в именах времени компоновки, вы может потребоваться дополнительная обработка; например, может потребоваться использовать подчеркивание в качестве «escape-символа», чтобы можно было отличить

  • List_my.get -> List__my_get

от

  • List.my_get -> List_my__get

(По общему признанию, этот пример подходит, но как составитель компилятора, Я должен гарантировать, что различных идентификаторов в исходном коде сопоставляются с разными именами времени ссылки . В этом вся причина и цель искажения имен.)

37
ответ дан 26 November 2019 в 23:49
поделиться

Проще говоря, изменение имен - это процесс, с помощью которого компиляторы изменяют имена идентификаторов в исходном коде, чтобы помочь компоновщику устранить неоднозначность между этими идентификаторами.

В Википедии есть замечательная статья. по этой теме с несколькими замечательными примерами.

24
ответ дан 26 November 2019 в 23:49
поделиться

Изменение имени - это средство, с помощью которого компиляторы изменяют "скомпилированное" имя объекта, чтобы оно согласованно отличалось от указанного вами.

Это позволяет язык программирования - гибкость, позволяющая давать одно и то же имя нескольким скомпилированным объектам и иметь согласованный способ поиска соответствующего объекта. Например, это позволяет нескольким классам с одним и тем же именем существовать в разных пространствах имен (часто путем добавления пространства имен к имени класса и т. Д.).

Перегрузка операторов и методов на многих языках делает этот шаг дальше - каждый метод заканчивается с "искаженным" именем в скомпилированной библиотеке, чтобы позволить нескольким методам одного типа существовать с одним и тем же именем.

4
ответ дан 26 November 2019 в 23:49
поделиться

В python изменение имен - это система, при которой переменные класса имеют разные имена внутри и вне класса. Программист "активирует" его, помещая два символа подчеркивания в начале имени переменной.

Например, я могу определить простой класс с некоторыми членами:

>>> class Foo(object):
...  def __init__(self):
...   self.x = 3
...   self._y = 4
...   self.__z = 5
... 

В практике Python имя переменной, начинающееся с символа подчеркивания, - " внутренний ", а не часть интерфейса класса, поэтому программисты не должны полагаться на него. Тем не менее, это все еще видно:

>>> f = Foo()
>>> f.x
3
>>> f._y
4

Имя переменной, начинающееся с двух знаков подчеркивания, по-прежнему является общедоступным, но оно искажено, и поэтому к нему труднее получить доступ:

>>> f.__z  
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__z'

Однако если мы знаем, как работает изменение имени, мы можем получить на это:

>>> f._Foo__z
5

т.е. имя класса добавляется к имени переменной с дополнительным подчеркиванием.

Python не имеет понятия «частный» или «открытый» члены; все публично. Изменение имени - это самый сильный сигнал, который может послать программист, что к переменной нельзя обращаться извне класса.

2
ответ дан 26 November 2019 в 23:49
поделиться

В Фортране изменение имени необходимо, потому что язык нечувствителен к регистру, а это означает, что Foo, FOO, fOo, foo и т. Д. Будут преобразованы в один и тот же символ, имя которого должно быть нормализовано в каким-то образом. Различные компиляторы реализуют искажение по-разному, и это является источником больших проблем при взаимодействии с C или двоичными объектами, скомпилированными с помощью другого компилятора. Например, GNU g77 / g95 всегда добавляет завершающий знак подчеркивания к имени в нижнем регистре, если имя уже не содержит одного или нескольких подчеркиваний. В этом случае добавляются два символа подчеркивания.

Например, следующая процедура

    program test
    end program 

    subroutine foo()
    end subroutine

    subroutine b_ar()
    end subroutine
    subroutine b_a_r()
    end subroutine

производит следующие искаженные символы:

0000000000400806 g     F .text  0000000000000006              b_ar__
0000000000400800 g     F .text  0000000000000006              foo_
000000000040080c g     F .text  0000000000000006              b_a_r__

Чтобы вызвать код Fortran из C, необходимо вызвать правильно измененное имя подпрограммы (очевидно, сохраняя учитывать возможные различные стратегии искажения, чтобы быть действительно независимыми от компилятора). Чтобы вызвать код C из fortran, интерфейс, написанный на C, должен экспортировать правильно искаженные имена и перенаправить вызов в подпрограмму C. Затем этот интерфейс можно вызвать из Фортрана.

0
ответ дан 26 November 2019 в 23:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: